【问题标题】:Segmentation fault in C txt file I/OC txt 文件 I/O 中的分段错误
【发布时间】:2013-10-06 23:50:31
【问题描述】:

好的,伙计们,我的程序的目的是从一个名为 orginal.txt 的文本文件中读取,其中包含以下格式的名称:

Kyle Butler
Bob Jones
Nathan Moore

然后程序将这些名称一次取一个,然后将它们转换成如下形式:

Kyle.Butler@emailaddress.com

然后,该地址会逐行存储在名为 final.txt 的新文本文件中

问题是,我无法让它工作,它给了我一个分段错误,甚至无法写入 final.txt

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void write(char line[100]);

int main()
{
    FILE *fp;
    fp = fopen("original.txt", "r+");

    char line[100];
    char mod[30]="@fakeemail.com\n";
    while (fgets(line, 100, fp) != NULL){
        int i;
        for(i=0; i<100; ++i){
            if(line[i]==' '){
                line[i]='.';
            }
            if(line[i]=='\n'){
                line[i]='\0';
            }
            strcat(line, mod);
        }



        FILE *fp2;
        fp2 = fopen("final.txt", "a");

        if (fp2 != NULL){
            fputs(line, fp2);
            fclose(fp2);
        }

    }

    fclose(fp);





    return 0;
}

【问题讨论】:

  • 段错误发生在哪里?在这条线上? strcat(line, mod);
  • 作为升级,您可能需要考虑是否需要为每次写入打开和关闭输出文件。
  • 您是否定义了一个名为write 的自己的函数?已经有一个名为write 的C 库例程。您可能应该选择一个对我们的应用程序更独特的名称。 write 很笼统。
  • 始终检查 fopen() 的返回值。它迟早会咬你。
  • 并且总是检查 fclose() 的返回值:stackoverflow.com/questions/19056309/…

标签: c file-io segmentation-fault


【解决方案1】:

代码有几个问题,但是分段错误很可能是这个for循环引起的:

for(i=0; i<100; ++i){
    if(line[i]==' '){
        line[i]='.';
    }
    if(line[i]=='\n'){
        line[i]='\0';
    }
    strcat(line, mod);
}

每次循环都将mod 连接到line。由于您重复循环 100 次而没有其他选项来退出循环,并且 line 的长度只有 100 个字符,很快您就会将 line 的第 100 个字符写入内存的其他部分。

【讨论】:

  • +1 相当肯定 strcat 应该在循环之外,这也将解决这个答案指出的问题。
  • 干杯,我记得看到那个并认为它看起来有点不合适:)
【解决方案2】:

建议的更改:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXLEN 100   /* Somehow parameterize "100" */

void write(char line[100]);

int main()
{
    FILE *fp;
    fp = fopen("original.txt", "r+");
    if (!fp) {   /* Check for error */
      perror ("open failed");
      return 1;
    }
    char line[MAXLEN];
     /* You don't need hard-coded array length with a static string */
    char *mod="@fakeemail.com\n"; 
    while (fgets(line, MAXLEN, fp) != NULL){
        int i;
        /* You don't need to iterate through more characters than the string contains */
        for(i=0; i<strlen(line); ++i){
            if(line[i]==' '){
                line[i]='.';
            }
            if(line[i]=='\n'){
                line[i]='\0';
            }
        }
        /* Move this OUTSIDE of your for loop */
        strcat(line, mod);

        /* Append to the output file */
        FILE *fp2;
        fp2 = fopen("final.txt", "a");
        /* You're checking for error: good! */
        if (fp2 != NULL){
            fputs(line, fp2);
            fclose(fp2);
        }

    }

    fclose(fp);
    return 0;
}

【讨论】:

  • 您真的会在条件表达式中调用strlen(),而不是仅使用本地char* 遍历字符串,直到命中空字符(并抛出100-step for-过程中的循环)?还是这只是您所针对的最小更改?
【解决方案3】:

正如 mbratch 所写,您在行数组中写入超过 100 个字符。这是一个工作代码:

void write(char line[100]);

int main()
{
    FILE *fp;
    fp = fopen("original.txt", "r+");

    char line[100];
    char mod[30]="fakeemail.com\n";
    while (fgets(line, 100, fp) != NULL){
        int i;
        for(i=0; i<100; ++i){
            if(line[i]==' '){
                line[i]='.';
            }
            if(line[i]=='\n'){
                line[i]='@'; strcat(line, mod);
                line[i+strlen(mod)]='\0';
            }
        }
        FILE *fp2;
        fp2 = fopen("final.txt", "a");

        if (fp2 != NULL){
            //fputs(line, fp2); printf("%s\n",line);
            fprintf(fp2,"%s\n",line);
            fclose(fp2);
        }
    }

    fclose(fp);
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-04
    • 1970-01-01
    • 2015-01-21
    • 1970-01-01
    • 2021-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多