【问题标题】:***Reading from file in C*** using fscanf, Scanning and printing a char that doesn't exist in .txt file***使用 fscanf 从 C 中的文件读取文件,扫描并打印 .txt 文件中不存在的字符
【发布时间】:2018-03-25 00:48:52
【问题描述】:

大家好,感谢您的点击!(讨厌被卡住)

我正在尝试将一个文件中的 char 值 fscanf 到我的结构中的一个变量。 当我扫描时,我收到一封与我想要得到的完全不同的信。问题出在我的 readfile 函数中。如果我解决了这个问题,我希望我可以扫描我需要进行算术运算的数字。我的教授正在教我们 FCFS(与 OS 调度算法有关,而不是 FCFS 数据结构队列课程)。所以文本文件列的意思是(PAS.txt):

进程名称 |到达时间 |服务时间

   A    0   3
   B    2   6
   C    4   4
   D    6   5
   E    8   2  

//Main.c
#include <stdio.h>
#include <time.h>
#include "lab8Func.h"


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

struct FCFS process;

readFile(&process);

printf("%s",&process.jobList[0].processName)

 }

//lab8func.h
#ifndef lab8Func_h
#define lab8Func_h
struct Job
{
    char processName;
    int arrivalTime;
    int serviceTime;
    int TAT;
    int NTAT;

};

struct FCFS
{
    struct Job jobList[5];

};

void readFile(struct FCFS*);

#endif /* lab8Func_h */

#include <stdio.h>
#include "lab8Func.h"


void readFile(struct FCFS *process1)
{  
FILE *file;
char temp;
int tempAT;
int tempST;



if((file = fopen("/Users/Vin/desktop/PAS.txt","r")) == NULL)
printf("Error, File Not Open.");
else
 {


    for(int i=0 ; i < 1; i++)
     {

         temp = fscanf(file," %c", &temp);  // where I'm stuck..
         process1->jobList[i].processName = temp;


        }


    }

}

输出

bProgram ended with exit code: 0 

***小写b ??如何 ?我在找大写A!!*****

【问题讨论】:

  • 1) fscanf 返回成功读取的元素数。 temp = fscanf(file," %c", &amp;temp); --> fscanf(file, " %c", &amp;temp);
  • 2) printf("%s",&amp;process.jobList[0].processName) --> printf("%c", process.jobList[0].processName)
  • 函数:main() 有两个有效签名。这些签名是:int main( int argc, char *argv[] )int main( void )。如果不打算使用传递的参数,则使用签名:int main( void )。编译时,始终启用警告,然后修复这些警告。 (对于gcc,至少使用:`-Wall -Wextra -pedantic -Wconversion -std=gnu11)
  • 函数中:readFile(),局部变量tempAttempSt没有被使用,所以应该去掉。
  • 在调用 fopen() 和 fscanf() 等系统函数时,始终检查返回值以确保操作成功。注意:fscanf() 返回一个整数,其中包含成功输入的成功输入/格式说明符的数量或 EOF。它不会返回 char&amp;temp 参数获取从(在这种情况下)file 读取的值。将函数的返回值分配给 temp 只是用一些 1 字节的整数值覆盖 temp。建议:if( 1 != fscanf(file," %c", &amp;temp) ) { // handle error and exit }

标签: c io scanf


【解决方案1】:

以下建议代码:

  1. 干净编译
  2. 自行清理(在这种情况下关闭输入文件
  3. 检查和处理错误
  4. 将错误消息输出到stderr 而不是stdout
  5. 遇到问题时退出
  6. 不包含“神奇”数字。 IE。硬编码的“5”
  7. 从输入文件中读取最多 5 行,而不是仅仅一行
  8. 更正了发布代码中的(几个)语法错误
  9. 执行所需的功能
  10. 仍然使用fscanf(),尽管更好的调用是fgets(),因为这样可以消除包含getc()的代码块
  11. 消除不需要的局部变量
  12. main() 函数使用正确的签名
  13. 记录包含每个头文件的原因
  14. 遵循公理:每行只有一个语句,并且(最多)每个语句有一个变量声明。
  15. 将变量声明保留在使用它的地方。
  16. 努力改进传递给函数的变量的“意义”:readFile()

警告:我将代码布局(为方便起见)修改为都在一个文件中

现在建议的代码:

#include <stdio.h>   // fopen(), fclose(), fscanf(), perror()
#include <stdlib.h>  // exit(), EXIT_FAILURE
//#include <time.h>
//#include "lab8Func.h"

//lab8func.h
#ifndef lab8Func_h
#define lab8Func_h

#define MAX_RECORDS 5

struct Job
{
    char processName;
    int  arrivalTime;
    int  serviceTime;
    int  TAT;
    int  NTAT;

};

struct FCFS
{
    struct Job jobList[ MAX_RECORDS ];
};

void readFile(struct FCFS*);

#endif /* lab8Func_h */



int main( void )
{
    struct FCFS jobs;

    readFile(&jobs);

    printf("%c", jobs.jobList[0].processName);
} // end function: main


void readFile(struct FCFS *jobs)
{
    FILE *file = NULL;

    if((file = fopen("/Users/Vin/desktop/PAS.txt","r")) == NULL)
    {
        perror( "fopen failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, fopen successful

    for(int i=0 ; i < MAX_RECORDS; i++)
    {
        char temp;
        if( 1 != fscanf(file," %c", &temp ) )
        { // handle error and exit
             perror( "fscanf failed" );
             fclose( file );  // cleanup
             exit( EXIT_FAILURE );
        }

        // implied else, fscanf successful

        jobs->jobList[i].processName = temp;

        // finish inputting the current line from the file
        int ch;
        while( (ch = getc( file ) ) != EOF && '\n' != ch )
        {
            ;
        }
    }

    fclose( file );   // cleanup
}  // end function:  readFile

【讨论】:

    【解决方案2】:

    首先,fscanf 的返回值是成功写入的参数数量(或失败时的 EOF)。所以你正在覆盖你的临时变量。

    temp = fscanf(file," %c", &temp);
    

    其次,这个打印语句是错误的:

    printf("%s",&process.jobList[0].processName)
    

    %s 表示打印一个以空字符结尾的字符串,并且您将一个指向字符的指针传递给它。它们都是 char * 类型,这就是它编译的原因,但它们的调用方式无法预期工作并且可能会崩溃。

    printf("%c",process.jobList[0].processName)
    

    第三,您忘记使用 fscanf 读取循环内的所有三列。

    【讨论】:

    • 我知道我没有读取所有列,循环只执行一次,如果我无法获得第一个字符,我不会尝试整数。好的,我将把“s”改成“c”。
    【解决方案3】:

    应记住一件事,您应该始终查看fscanfscanf for checking,如果它返回真或假(任何整数值或0),即它是否以正确的格式读取,然后进一步处理。

    你需要在 readFile 函数的 for 循环中修改你的代码:

       if((check=fscanf(file," %c", &temp))>0) 
          process1->jobList[i].processName = temp;
    

    【讨论】:

    • 太好了,这很有意义,我会改变它。谢谢!
    猜你喜欢
    • 2016-05-28
    • 2013-05-06
    • 2012-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-10
    • 2021-04-02
    • 2022-01-14
    相关资源
    最近更新 更多