我有一个文件,看起来如下:
ATOM HIS
ATOM TRP
ATOM PHE
我想打印第一列,以下是我的C代码:
#include<stdio.h>
#includ<stdlib.h>
void main
{
FILE *fp;
fp=fopen("xyz","r");
char *atm,*res;
char buff[200];
while(fgets(buff,sizeof (buff),fp)!=NULL){
i++;
}
rewind(fp);
atm=(char*)malloc(i * sizeof (char*));
res=(char*)malloc(i * sizeof (char*));
while(fgets(buff,sizeof (buff),fp)!=NULL){
fscanf(fp,"%s %s",&atm[i],&res[i]);
i++;
}
for(j=0;j<i;j++){
printf("%sn",atm);
}
我希望以下输出:
ATOM
ATOM
ATOM
,但没有编译并说:
warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’
因此,在printf
语句中,我已将&
添加到atm
(即ATM而不是ATM)。在这种情况下,代码编译良好,但给出以下输出:
AAAAAAAAAAAAAAAATOM
AAAAAAAAAATOM
AAAAAAAATOM
我将感谢有关此的任何建议。
首先,
atm=(char*)malloc(sizeof (char*));
不做您认为的做。它只能分配足够的内存o o保存 char *
,这也是错误的。
您需要分配n * sizeof(char)
的大小,其中n
== char
s的数字。现在,通过C标准保证sizeof(char) == 1
,您的陈述可以简化为
atm = malloc(requiredsize);
res= malloc(requiredsize);
之后,您应该检查malloc()
调用的成功,以防止UB访问Null指针。
但是,您将在每次呼叫fgets()
和fscanf()
中覆盖atm
和res
。您似乎需要一系列指针,而不是一个简单的指针来完成工作。
如果atm
和res
是char *
数组的指针,这似乎是意图,则应将其声明为这样:
char **atm,**res;
然后,您需要为每个字符串分配存储,以及整个数组:
while(fgets(buff,sizeof (buff),fp)!=NULL){
atm[i] = malloc(200); // choose a suitable maximum size
res[i] = malloc(200);
fscanf(fp,"%s %s",atm[i],res[i]);
i++;
}
这与您的意图更加紧密 - 我认为。
但是,这不是特别好的做法。将fscanf
与%s
一起使用,无法保证您读取的字符串不会比分配的内容更长(我认为您可以使用宽度指定限制限制其读取的内容,例如%100s
,但这限制了读取多少以及存储多少)。您还应在每种情况下检查malloc
的返回以确保成功。