【问题标题】:Compiler showing warnings even though code is working即使代码正在运行,编译器也会显示警告
【发布时间】:2021-05-05 16:39:12
【问题描述】:

我一直在解决这个问题:

编写一个程序,将两个文件中的行交替合并并将结果写入新文件。如果一个文件的行数少于另一个,则应将较大文件中的剩余行简单地复制到目标文件中。

这是我的代码:

#include <stdio.h>
#include <stdlib.h>
int main(){
    
    FILE *fp;
    FILE *fp1;
    FILE *fp2;
    fp=fopen("sample3.txt","r");
    fp1=fopen("sample4.txt","r");
    fp2=fopen ("output.txt","w");
    char a[100];
    char b[100];
    int *p;
    int *c;
    while (1){
        if (p=fgets(a,100,fp)!=NULL){
            fputs (a,fp2);
        }
        if (c=fgets(b,100,fp1)!=NULL){
            fputs (b,fp2);
        }
        if (c==NULL && p==NULL){
            break;
        }
        }
    return 0;
    }

虽然 output.txt 文件包含来自这两个文件的字符串,但编译器显示 [警告] 在以下两行中赋值使指针从整数而不进行强制转换:

如果 (c=fgets(b,100,fp1)!=NULL)

如果 (p=fgets(a,100,fp)!=NULL)

有人可以帮忙吗?

【问题讨论】:

  • 警告就是这样,他们基本上是在说这是模棱两可和/或潜在的危险,并且可能会或可能不会按您预期的方式工作。 -- 如果您想要一个好的答案,请发布确切的警告消息并在源代码中标记它适用的行。
  • @500-InternalServerError 查看已编辑的问题
  • 是的,所以fgets 返回一个char*,那你为什么将cp 声明为int*
  • 你为什么要使用 fgets?最好使用fgetc 完成此操作。一次读一个字符。当您看到\n 时,请更改输入源。

标签: c file pointers compiler-warnings


【解决方案1】:

表达式:

c = fgets(b, 100, fp1) != NULL

相当于:

c = (fgets(b, 100, fp1) != NULL)

因为!= 的优先级高于=,因此这会将比较中的布尔整数转换为指针。您应该使用显式括号来解决此问题:

(c = fgets(b, 100, fp1)) != NULL

这将对c 进行赋值(因为括号赋予该操作更高的优先级)然后将该值与NULL 进行比较。

【讨论】:

    【解决方案2】:

    两个问题:

    1. pc 是指向错误类型的指针(int 而不是 char
    2. 如果语句错误。它用逻辑表达式的结果分配指针。逻辑表达式的结果可以是10,它们是整数,因此发出警告。您需要先分配指针,然后进行比较。
        char *p;
        char *c;
        while (1){
            if ((p=fgets(a,100,fp))!=NULL){
                fputs (a,fp2);
            }
            if ((c=fgets(b,100,fp1))!=NULL){
    

    【讨论】:

      【解决方案3】:

      没有任何括号,你正在这样做:

      if (c= (fgets(b,100,fp1)!=NULL) )
      

      比较的结果是int,这就是您分配给char* c 的结果。你可以打印它,你会看到它要么是1(当fgets()返回NULL以外的东西)或0(如果fgets()返回NULL)。

      你想要的是以下内容:

      if ( (c=fgets(b,100,fp1)!=NULL) )
      

      甚至更好(直到您更精通组合多个语句)

      c= fgets(b,100,fp1);
      if ( c!=NULL )
      

      第二行也必须这样做。另外,将pcint* 更改为char*

      【讨论】:

      • 您的第一个解决方案根本没有帮助。
      【解决方案4】:

      以下建议的代码:

      1. 干净编译
      2. 允许超过 99 个字符的行
      3. 检查所有 I/O 错误
      4. 报告stderr 上的 I/O 错误
      5. 执行所需的功能
      6. 给出“神奇”数字,例如 100,有意义的名称
      7. 可以轻松“调整”,因此一旦遇到 EOF,该文件将不再读取

      现在,建议的代码:

      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      
      #define MAX_LINE_LEN 100
      
      
      int main( void )
      {
          
          FILE *fp = fopen( "sample3.txt", "r" );
          if( ! fp )
          {
              perror( "fopen to read: sample3.txt failed" );
              exit( EXIT_FAILURE );
          }
          
          FILE *fp1 = fopen( "sample4.txt", "r" );
          if( ! fp1 )
          {
              perror( "fopen to read: sample4.txt failed" );
              fclose( fp );
              exit( EXIT_FAILURE );
          }
          
          FILE *fp2 = fopen ( "output.txt", "w" );
          if( ! fp2 )
          {
              perror( "fopen to write: output.txt failed" );
              fclose( fp );
              fclose( fp1 );
              exit( EXIT_FAILURE );
          }
          
          char buffer[ MAX_LINE_LEN ];
      
          char *ap = NULL;
          char *bp = NULL;
          
          do
          {
              do
              {
                  if ( (ap = fgets(buffer, sizeof( buffer ),fp) ) != NULL )
                  {  // then read successful
                      if( EOF == fputs ( buffer, fp2 ) )
                      {  // then, write failed
                          perror( "fputs failed" );
                          break;
                      }
                  }
                  else
                  { // else, read failed
                      perror( "fgets failed" );
                      break;
                  }
              // while end of line not found
              } while( strchr( buffer, '\n' ) == NULL ); 
              
              do
              {
                  if ( (bp = fgets(buffer, sizeof( buffer ),fp1) ) != NULL )
                  {
                      if( EOF == fputs ( buffer, fp2 ) )
                      {
                          perror( "fputs failed" );
                          break;
                      }
                  }
                  else
                  {
                      perror( "fgets failed" );
                      break;
              } while( strchr( buffer, '\n' ) == NULL );
          // while more to read
          } while( ap || bp );
          
          fclose( fp );
          fclose( fp1 );
          fclose( fp2 );
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-20
        • 1970-01-01
        相关资源
        最近更新 更多