如何检查fscanf()在C中返回有效字符串?

如何检查fscanf()在C中返回有效字符串?,c,string,scanf,C,String,Scanf,我有一个C/fscanf()问题。完整免责声明:我是CS学生,正在做作业。我的代码有效,但评分员将使用GCC“所有错误和警告”选项编译我们的提交: 我的代码工作正常,但我收到了一个警告,这让我很烦。。。并可能导致平地机出现问题。我的代码很简单,它将文件的每一行扫描成一个字符串,然后将该字符串抛给函数: #include<stdio.h> #include<stdlib.h> #include<string.h> void printString(char*

我有一个C/fscanf()问题。完整免责声明:我是CS学生,正在做作业。我的代码有效,但评分员将使用GCC“所有错误和警告”选项编译我们的提交:

我的代码工作正常,但我收到了一个警告,这让我很烦。。。并可能导致平地机出现问题。我的代码很简单,它将文件的每一行扫描成一个字符串,然后将该字符串抛给函数:

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

void printString(char* string){
    printf("file line is:  \"%s\"\n", string);
}

int main(int argc, char *argv[]){

    char *myFile = argv[1];
    FILE *targetFile;
    targetFile = fopen(myFile, "r");

    if (targetFile == NULL) {
        // some problem with the input file
        return -1;
    } else {
        char* string;
        while (fscanf(targetFile, "%s\n", string) != EOF){
            printString(string);
        }
    }
    fclose(targetFile);
    return 1;
}
我明白了编译器想要说的:“如果‘string’没有保存有效的数据怎么办?”这是一个有效的观点;我假设输入文件的每一行都会产生一个工作字符串

那么:如何检查这一点,并摆脱恼人的警告?我注意到fscanf()返回成功扫描的项目数,因此我尝试了以下方法:

    int num = 1;    // initialize to something >0
    while (num = (fscanf(targetFile, "%s\n", string) != EOF) > 0){
        printString(string);
    }
但这产生了两个警告:

$ gcc -Wall myCode.c
myCode.c: In function ‘main’:
myCode.c:21:3: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
   while (num = (fscanf(targetFile, "%s\n", string) != EOF) > 0){
   ^
myCode.c:22:4: warning: ‘string’ may be used uninitialized in this function [-Wmaybe-uninitialized]
    printString(string);
    ^
$
另外,我担心如果fscanf()出于某种合理的原因返回0,这会导致程序过早停止读取文件

所以。。。不知道该怎么解决这个问题。在Java中,我只想说“if(string!=NULL)…”然后继续。但在C中不能这样做。在调用外部函数之前,必须有一些快速的方法来检查fscanf()是否获取了有效字符串

有人知道怎么解决吗

谢谢! -皮特


PS-如果这是GCC问题而不是C问题,请道歉:(

string
在代码中是指针而不是数组。没有为
fscanf
分配内存将字符复制到其中。将其更改为字符数组将起到与
string=malloc(X)相同的作用
其中X是要分配的字节数。请记住,字符串的'\0'终止需要一个额外的字节。还请记住,您不知道测试行可能有多大,
fscanf
只会复制字节而不考虑长度,这带来了另一个问题--
fscanf
s如何您是否知道要复制整行而不是一个单词或字符?您应该仔细研究一下!代码中的字符串是指针而不是数组。没有为
fscanf
分配内存来将字符复制到其中。将其更改为字符数组将起到与
string=malloc(X)相同的作用
其中X是要分配的字节数。请记住,字符串的'\0'终止需要一个额外的字节。还请记住,您不知道测试行可能有多大,
fscanf
只会复制字节而不考虑长度,这带来了另一个问题--
fscanf
s如何你知道复制一整行而不是一个单词或一个字符吗?你应该仔细研究一下

如何检查fscanf()在C中返回有效字符串

1) 确保提供空间以保存数据2)限制读取的数据量3)测试输入函数的结果

    // #1 Provide space  `char* string` is simple a pointer with an uninitialized value
    // char* string;
    // Select a reasonable upper bound: recommend 2x expected max size
    char string[100];

    // #2 Limit width to reading up to 99 characters, 
    // 1 less than buffer size as `fscanf()` will append a null character
    // while (fscanf(targetFile, "%s\n", string) != EOF){
    // while (fscanf(targetFile, "%99s\n", string) != EOF){

    // #3 Check against the desired success value, 
    //   do not check against one of the undesired values
    while (fscanf(targetFile, "%99s\n", string) == 1) {
如何检查fscanf()在C中返回有效字符串

1) 确保提供空间以保存数据2)限制读取的数据量3)测试输入函数的结果

    // #1 Provide space  `char* string` is simple a pointer with an uninitialized value
    // char* string;
    // Select a reasonable upper bound: recommend 2x expected max size
    char string[100];

    // #2 Limit width to reading up to 99 characters, 
    // 1 less than buffer size as `fscanf()` will append a null character
    // while (fscanf(targetFile, "%s\n", string) != EOF){
    // while (fscanf(targetFile, "%99s\n", string) != EOF){

    // #3 Check against the desired success value, 
    //   do not check against one of the undesired values
    while (fscanf(targetFile, "%99s\n", string) == 1) {

char*字符串-->
字符字符串[1024]
char*string
创建指向字符串的指针。它不分配内存来保存该字符串。您可以使用
char-string[256]
char*string=malloc(…)
。当针对只包含几行的文本文件运行时,您的代码对我来说是错误的,因为正如其他人所说,您没有分配内存来保存字符串。我不知道您的输入应该是什么(请确保下次在您的问题中包含该条件),但我不确定您在询问编译器警告之前是如何没有发现代码错误的。另外,我建议
while(fscanf(targetFile,“%s\n”,string)==1)
因为如果返回值为
0
,您的版本将失败。这对于
%s
输入可能永远不会这样做,但当您扫描数字类型或多个字符串时,检查转换的参数数量是否与请求匹配很重要,因此这是一种更好的做法。
char*string创建一个字符串指针
哪个字符串准确?
char*string-->
字符字符串[1024]
char*string
创建指向字符串的指针。它不分配内存来保存该字符串。您可以使用
char-string[256]
char*string=malloc(…)
。当针对只包含几行的文本文件运行时,您的代码对我来说是错误的,因为正如其他人所说,您没有分配内存来保存字符串。我不知道您的输入应该是什么(请确保下次在您的问题中包含该条件),但我不确定您在询问编译器警告之前是如何没有发现代码错误的。另外,我建议
while(fscanf(targetFile,“%s\n”,string)==1)
因为如果返回值为
0
,您的版本将失败。对于
%s
输入可能永远不会这样做,但当您扫描数字类型或多个字符串时,检查转换的参数数量是否与请求匹配非常重要,因此这是一种更好的做法。
char*string创建一个指向字符串的指针
哪个字符串准确?我对您的答案投了赞成票,但你不应该说
将其更改为字符数组将起作用
,因为你永远不知道他/她为什么使用
char*
而不是
char[]
谢谢Nategose,你说得太对了。这种malloc()/free()的习惯很难养成,尤其是在第一次学习Java之后。谢谢你的帮助!我对你的答案投了赞成票,但你不应该说
将其更改为字符数组将起作用
,因为你永远不知道他/她为什么使用
char*
而不是
char[]
谢谢Nategose,你说得太对了。这个malloc()/free()习惯很难养成
    // #1 Provide space  `char* string` is simple a pointer with an uninitialized value
    // char* string;
    // Select a reasonable upper bound: recommend 2x expected max size
    char string[100];

    // #2 Limit width to reading up to 99 characters, 
    // 1 less than buffer size as `fscanf()` will append a null character
    // while (fscanf(targetFile, "%s\n", string) != EOF){
    // while (fscanf(targetFile, "%99s\n", string) != EOF){

    // #3 Check against the desired success value, 
    //   do not check against one of the undesired values
    while (fscanf(targetFile, "%99s\n", string) == 1) {