【问题标题】:C strcat inserts garbage into stringC strcat将垃圾插入字符串
【发布时间】:2021-11-05 10:19:13
【问题描述】:

我的方法读取具有以下格式的向量输入文本:

57.0000,-7.4703,-0.3561
81.0000,-4.6478,7.9474
69.0000,-8.3768,0.4391
18.0000,-4.9377,9.9903
62.0000,-5.8751,-6.6054
...

我尝试读取每个向量并将其插入数组如下:

FILE *file;
int n = 1, dim, i=0;
char* str;
double ret;
double* X;
int c;
int com=0;
assert(argc==2 && "argc != 2");
file = fopen(argv[1], "r");
assert(file && "file is empty");
for(c = getc(file); c!= EOF; c = getc(file)){
   if(c == '\n'){
        n++;
   }
   else if(c==','){
       com++;
   }
}
dim = com/n +1;
char* str;
double ret;
double* X;
X = (double *)calloc(n*n, sizeof(double));
assert(X); 
str = (char *)calloc(100, sizeof(char));
assert(str); 
for(c = getc(file); c!= EOF; c = getc(file)){
     if(c!=',' && c!= '\n'){
       strcat(str, &c);      
     }
     else{
     ret = strtod(str, NULL);
     X[i] = ret;
     i++;
     memset(str, 0, 100 * sizeof(char)); 
     }
}

问题在于,当它到达每一行的最后一个向量时,它会读取每个字符并将其与额外的垃圾连接到 str 中。任何想法如何解决这个问题?

【问题讨论】:

  • c的类型没有显示(编辑前),但是肯定不适合传给strcat,因为你有c = getc(file)所以应该是int类型。
  • 卡哈隆,第一步:char c; --> int c;
  • strcat(str, &c); 无效,因为&c 不指向字符串
  • 请记住,'-' 是类型 int 而不是 char。不使用 int 就无法测试 EOF,这是库函数 getc 返回的结果,不是 char
  • 然后阅读@chux 的评论。你不能strcat一个字符,你需要一个字符串。

标签: c file strcat garbage getc


【解决方案1】:

strcat 期望以 NUL 结尾的字符串(char 数组)作为其第二个参数,但是 c 定义为单个字符,而不是字符数组。

要解决此问题,您可以在str 中维护一个索引

int c;
int j = 0;
for (c = getc(file); c!= EOF; c = getc(file)) {
    if (c != ',' && c != '\n') {
        str[j++] = c;
        str[j] = 0; // keep string NUL-terminated
    } else {
        ret = strtod(str, NULL);
        X[i] = ret;
        i++;
        // reset j
        j = 0;
    }
}

【讨论】:

    【解决方案2】:

    由于cchar,所以下面是无效的。

    c = getc(file); c!= EOF;  
    

    strcat(str, &c);
    

    两者都是未定义的行为。要对第一个进行排序,请将 c 声明为 int

    第二个问题:

    //You need to create a null char terminated string to use as 
    //second parameters of the srtcat. For example, you can define 
    //a compound literal - char array containing two elements: c & 
    //terminating null character
    strcat(str,(char []){c,0});
    

    【讨论】:

    • c = getc(file); c!= EOF; 不是 UB,但代码仍然很差。使用 复合文字 很不错。
    • 我不想过多地更改 OPs 代码
    • 足够公平,可以限制对 OP 代码的更改,但答案的解释仍然有问题。
    猜你喜欢
    • 2020-04-19
    • 2016-03-14
    • 2016-03-03
    • 1970-01-01
    • 1970-01-01
    • 2015-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多