调用 fscanf 时数组更改第一个值而不显式修改它

发布于 2024-12-05 05:37:04 字数 9586 浏览 1 评论 0原文

我正在从 std in 读取一个值并将其存储在数组 min[3] 中,然后继续进行数组比较。所以在比较之前从未触及min

调试后,我注意到执行此行后 min[0] 从输入值更改为 \0

fscanf(locDayFile, "%s", extractedHour);

其中 locDayFile 和 < code>extractedHour 声明如下:

FILE* locDayFile;
char extractedHour[3];

关于出了什么问题有什么想法吗?

编辑在这里我发布代码:

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

struct coords{
    float coord[3];
    char station[5];
    struct coords *next;
};

void Add(struct coords**,char*, float*);
float* Get(struct coords*, char*);

int main(){

    DIR *rootFolder, *subFolder;
    struct dirent *rootEnt, *subEnt;
    char rootFolderName[260], subFolderName[260];

    FILE *locDayFile,  *headers, *coordFile;
    FILE *stationDay, *yearDay, *time, *reference;
    char locDayFileName[260], headersFileName[260], coordFileName[260];
    char stationDayName[260], yearDayName[260], timeName[260], referenceName[260];
    char result[260];
    char make[260];

    char readLine[256];

    char searchingFolderName[9], folderCmp[9];

    char location[7], year[5], day[4], hour[3], min[3], referenceStation[5];
    char locationTest[7], dayTest[4];
    char extractedStation[5], extractedYear[5], extratedDay[4], extractedHour[3], extractedMin[3];
    char rms[7];
    float delay, refereDelay = 0;
    float *coordinates;

    char choice;

    printf("Please enter the following information:\n");
    printf("Location: ");
    scanf("%s", location);
    memmove(location+1, location, 4);
    location[0] = 'o';
    location[5] = 'a';
    location[6] = '\0';
    printf("Year: ");
    scanf("%s", year);
    printf("Day: ");
    scanf("%s", day);

    sprintf(searchingFolderName, "%s_%s", year, day);

    hour[0] = '\0';
    min[0] = '\0';
    referenceStation[0] = '\0';
    referenceName[0] = '\0';
    printf("Do you wish to enter the time?(Y/N): ");
    do{
        scanf("%c", &choice);
    }while(choice != 'Y' && choice != 'y' && choice != 'N' && choice != 'n');
    if(choice == 'Y' || choice == 'y'){
        printf("Hour: ");
        scanf("%s", hour);
        printf("Minutes: ");
        scanf("%s", min);
    }
    printf("Do you wish to enter a reference station?(Y/N): ");
    do{
        scanf("%c", &choice);
    }while(choice != 'Y' && choice != 'y' && choice != 'N' && choice != 'n');
    if(choice == 'Y' || choice == 'y'){
        printf("Reference station: ");
        scanf("%s", referenceStation);
    }

    printf("Root folder path: ");
    scanf("%s", rootFolderName);

    struct coords *c;
    c = NULL;

    printf("Coordinates file path: ");
    scanf("%s", coordFileName);
    coordFile = fopen(coordFileName, "r");
    if(coordFile != NULL){
        char st[5];
        float coords[3];
        while(!feof(coordFile)){
            fscanf(coordFile, "%s", st);
            fscanf(coordFile, "%f", &coords[0]);
            fscanf(coordFile, "%f", &coords[1]);
            fscanf(coordFile, "%f", &coords[2]);

            Add(&c, st, coords);
        }
    }

    if((rootFolder = opendir(rootFolderName)) != NULL){
        while((rootEnt = readdir(rootFolder)) != NULL){

            sprintf(result, "%sresults/", rootFolderName);
            sprintf(make, "mkdir -p %s", result);
            system(make);

            folderCmp[0] = '\0';
            strncpy(folderCmp, rootEnt->d_name, 8);
            folderCmp[8] = '\0';

            if(strcmp(folderCmp, searchingFolderName) == 0){

                sprintf(subFolderName, "%s%s/", rootFolderName, rootEnt->d_name);

                if((subFolder = opendir(subFolderName)) != NULL){
                    while((subEnt = readdir(subFolder)) != NULL){

                        strncpy(locationTest, subEnt->d_name, 6);
                        locationTest[6] = '\0';
                        strncpy(dayTest, (subEnt->d_name)+7, 3);
                        dayTest[3] = '\0';
                        if((strcmp(location, locationTest) == 0) && (strcmp(day, dayTest) == 0)){

                            sprintf(locDayFileName, "%s%s", subFolderName, subEnt->d_name);
                            locDayFile = fopen(locDayFileName, "r");

                            while(!feof(locDayFile)){

                                char garbage[25];

                                fscanf(locDayFile, "%s", garbage);
                                if(strcmp(garbage, "ATM_ZEN") == 0){

                                    sprintf(headersFileName, "%sheaders_%s-%s", rootFolderName, year, day);
                                    headers = fopen(headersFileName, "a+");

                                    fscanf(locDayFile, "%s", garbage);

                                    fscanf(locDayFile, "%s", extractedStation);//3rd column.
                                    fprintf(headers, "%s\t", extractedStation);

                                    fscanf(locDayFile, "%s", garbage);

                                    fscanf(locDayFile, "%s", extractedYear);//5th column.
                                    fprintf(headers, "%s\t", extractedYear);

                                    fscanf(locDayFile, "%s", garbage);

                                    fscanf(locDayFile, "%s", extratedDay);//7th column.
                                    fprintf(headers, "%s\t", extratedDay);

                                    fscanf(locDayFile, "%s", extractedHour);//8th column.
                                    fprintf(headers, "%s\t", extractedHour);

                                    fscanf(locDayFile, "%s", extractedMin);//9th column.
                                    fprintf(headers, "%s\t", extractedMin);

                                    fscanf(locDayFile, "%s", garbage);
                                    fscanf(locDayFile, "%s", garbage);

                                    fscanf(locDayFile, "%f", &delay);//12th column.
                                    fscanf(locDayFile, "%s", rms);//13 column.
                                    fprintf(headers, "%s\t", rms);
                                    fprintf(headers, "%f\n", delay);

                                    if(strcmp(referenceStation, extractedStation) == 0 && refereDelay == 0)
                                        refereDelay = delay;


                                    coordinates = Get(c, extractedStation);
                                    if(coordinates != NULL){
                                        //station_day file
                                        sprintf(stationDayName, "%s%s_%s", result, extractedStation, extratedDay);
                                        stationDay = fopen(stationDayName, "a+");
                                        fprintf(stationDay, "%s\t", extractedYear);
                                        fprintf(stationDay, "%s\t", extractedHour);
                                        fprintf(stationDay, "%s\t", extractedMin);
                                        fprintf(stationDay, "%f\t", coordinates[0]);
                                        fprintf(stationDay, "%f\t", coordinates[1]);
                                        fprintf(stationDay, "%f\t", coordinates[2]);
                                        fprintf(stationDay, "%s\t", rms);
                                        fprintf(stationDay, "%f\n", delay);
                                        fclose(stationDay);

                                        //year_day file
                                        sprintf(yearDayName, "%s%s_%s", result, extractedYear, extratedDay);
                                        yearDay = fopen(yearDayName, "a+");
                                        fprintf(yearDay, "%s\t", extractedStation);
                                        fprintf(yearDay, "%s\t", extractedHour);
                                        fprintf(yearDay, "%s\t", extractedMin);
                                        fprintf(yearDay, "%f\t", coordinates[0]);
                                        fprintf(yearDay, "%f\t", coordinates[1]);
                                        fprintf(yearDay, "%f\t", coordinates[2]);
                                        fprintf(yearDay, "%s\t", rms);
                                        fprintf(yearDay, "%f\n", delay);
                                        fclose(yearDay);

                                        //year_day_hour_min file
                                        if((hour[0] != '\0' && (strcmp(hour, extractedHour) == 0)) && (min[0] != '\0' && (strcmp(min, extractedMin) == 0))){
                                            sprintf(timeName , "%s_%s_%s", yearDayName, hour, min);
                                            time = fopen(timeName, "a+");
                                            fprintf(time, "%s\t", extractedStation);
                                            fprintf(time, "%f\t", coordinates[0]);
                                            fprintf(time, "%f\t", coordinates[1]);
                                            fprintf(time, "%f\t", coordinates[2]);
                                            fprintf(time, "%s\t", rms);
                                            fprintf(time, "%f\n", delay);
                                            fclose(yearDay);
                                        }
[.....]

I am reading a value from std in and storing it in an array min[3] and later on proceed to make an array comparison. Somin is never touched before the comparison.

After debugging, I noticed that min[0] changes from the input value to \0 upon the executon of this line:

fscanf(locDayFile, "%s", extractedHour);

where locDayFile and extractedHour are declared as such:

FILE* locDayFile;
char extractedHour[3];

Any ideas on what is going wrong ?

EDIT Here I am posting the code:

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

struct coords{
    float coord[3];
    char station[5];
    struct coords *next;
};

void Add(struct coords**,char*, float*);
float* Get(struct coords*, char*);

int main(){

    DIR *rootFolder, *subFolder;
    struct dirent *rootEnt, *subEnt;
    char rootFolderName[260], subFolderName[260];

    FILE *locDayFile,  *headers, *coordFile;
    FILE *stationDay, *yearDay, *time, *reference;
    char locDayFileName[260], headersFileName[260], coordFileName[260];
    char stationDayName[260], yearDayName[260], timeName[260], referenceName[260];
    char result[260];
    char make[260];

    char readLine[256];

    char searchingFolderName[9], folderCmp[9];

    char location[7], year[5], day[4], hour[3], min[3], referenceStation[5];
    char locationTest[7], dayTest[4];
    char extractedStation[5], extractedYear[5], extratedDay[4], extractedHour[3], extractedMin[3];
    char rms[7];
    float delay, refereDelay = 0;
    float *coordinates;

    char choice;

    printf("Please enter the following information:\n");
    printf("Location: ");
    scanf("%s", location);
    memmove(location+1, location, 4);
    location[0] = 'o';
    location[5] = 'a';
    location[6] = '\0';
    printf("Year: ");
    scanf("%s", year);
    printf("Day: ");
    scanf("%s", day);

    sprintf(searchingFolderName, "%s_%s", year, day);

    hour[0] = '\0';
    min[0] = '\0';
    referenceStation[0] = '\0';
    referenceName[0] = '\0';
    printf("Do you wish to enter the time?(Y/N): ");
    do{
        scanf("%c", &choice);
    }while(choice != 'Y' && choice != 'y' && choice != 'N' && choice != 'n');
    if(choice == 'Y' || choice == 'y'){
        printf("Hour: ");
        scanf("%s", hour);
        printf("Minutes: ");
        scanf("%s", min);
    }
    printf("Do you wish to enter a reference station?(Y/N): ");
    do{
        scanf("%c", &choice);
    }while(choice != 'Y' && choice != 'y' && choice != 'N' && choice != 'n');
    if(choice == 'Y' || choice == 'y'){
        printf("Reference station: ");
        scanf("%s", referenceStation);
    }

    printf("Root folder path: ");
    scanf("%s", rootFolderName);

    struct coords *c;
    c = NULL;

    printf("Coordinates file path: ");
    scanf("%s", coordFileName);
    coordFile = fopen(coordFileName, "r");
    if(coordFile != NULL){
        char st[5];
        float coords[3];
        while(!feof(coordFile)){
            fscanf(coordFile, "%s", st);
            fscanf(coordFile, "%f", &coords[0]);
            fscanf(coordFile, "%f", &coords[1]);
            fscanf(coordFile, "%f", &coords[2]);

            Add(&c, st, coords);
        }
    }

    if((rootFolder = opendir(rootFolderName)) != NULL){
        while((rootEnt = readdir(rootFolder)) != NULL){

            sprintf(result, "%sresults/", rootFolderName);
            sprintf(make, "mkdir -p %s", result);
            system(make);

            folderCmp[0] = '\0';
            strncpy(folderCmp, rootEnt->d_name, 8);
            folderCmp[8] = '\0';

            if(strcmp(folderCmp, searchingFolderName) == 0){

                sprintf(subFolderName, "%s%s/", rootFolderName, rootEnt->d_name);

                if((subFolder = opendir(subFolderName)) != NULL){
                    while((subEnt = readdir(subFolder)) != NULL){

                        strncpy(locationTest, subEnt->d_name, 6);
                        locationTest[6] = '\0';
                        strncpy(dayTest, (subEnt->d_name)+7, 3);
                        dayTest[3] = '\0';
                        if((strcmp(location, locationTest) == 0) && (strcmp(day, dayTest) == 0)){

                            sprintf(locDayFileName, "%s%s", subFolderName, subEnt->d_name);
                            locDayFile = fopen(locDayFileName, "r");

                            while(!feof(locDayFile)){

                                char garbage[25];

                                fscanf(locDayFile, "%s", garbage);
                                if(strcmp(garbage, "ATM_ZEN") == 0){

                                    sprintf(headersFileName, "%sheaders_%s-%s", rootFolderName, year, day);
                                    headers = fopen(headersFileName, "a+");

                                    fscanf(locDayFile, "%s", garbage);

                                    fscanf(locDayFile, "%s", extractedStation);//3rd column.
                                    fprintf(headers, "%s\t", extractedStation);

                                    fscanf(locDayFile, "%s", garbage);

                                    fscanf(locDayFile, "%s", extractedYear);//5th column.
                                    fprintf(headers, "%s\t", extractedYear);

                                    fscanf(locDayFile, "%s", garbage);

                                    fscanf(locDayFile, "%s", extratedDay);//7th column.
                                    fprintf(headers, "%s\t", extratedDay);

                                    fscanf(locDayFile, "%s", extractedHour);//8th column.
                                    fprintf(headers, "%s\t", extractedHour);

                                    fscanf(locDayFile, "%s", extractedMin);//9th column.
                                    fprintf(headers, "%s\t", extractedMin);

                                    fscanf(locDayFile, "%s", garbage);
                                    fscanf(locDayFile, "%s", garbage);

                                    fscanf(locDayFile, "%f", &delay);//12th column.
                                    fscanf(locDayFile, "%s", rms);//13 column.
                                    fprintf(headers, "%s\t", rms);
                                    fprintf(headers, "%f\n", delay);

                                    if(strcmp(referenceStation, extractedStation) == 0 && refereDelay == 0)
                                        refereDelay = delay;


                                    coordinates = Get(c, extractedStation);
                                    if(coordinates != NULL){
                                        //station_day file
                                        sprintf(stationDayName, "%s%s_%s", result, extractedStation, extratedDay);
                                        stationDay = fopen(stationDayName, "a+");
                                        fprintf(stationDay, "%s\t", extractedYear);
                                        fprintf(stationDay, "%s\t", extractedHour);
                                        fprintf(stationDay, "%s\t", extractedMin);
                                        fprintf(stationDay, "%f\t", coordinates[0]);
                                        fprintf(stationDay, "%f\t", coordinates[1]);
                                        fprintf(stationDay, "%f\t", coordinates[2]);
                                        fprintf(stationDay, "%s\t", rms);
                                        fprintf(stationDay, "%f\n", delay);
                                        fclose(stationDay);

                                        //year_day file
                                        sprintf(yearDayName, "%s%s_%s", result, extractedYear, extratedDay);
                                        yearDay = fopen(yearDayName, "a+");
                                        fprintf(yearDay, "%s\t", extractedStation);
                                        fprintf(yearDay, "%s\t", extractedHour);
                                        fprintf(yearDay, "%s\t", extractedMin);
                                        fprintf(yearDay, "%f\t", coordinates[0]);
                                        fprintf(yearDay, "%f\t", coordinates[1]);
                                        fprintf(yearDay, "%f\t", coordinates[2]);
                                        fprintf(yearDay, "%s\t", rms);
                                        fprintf(yearDay, "%f\n", delay);
                                        fclose(yearDay);

                                        //year_day_hour_min file
                                        if((hour[0] != '\0' && (strcmp(hour, extractedHour) == 0)) && (min[0] != '\0' && (strcmp(min, extractedMin) == 0))){
                                            sprintf(timeName , "%s_%s_%s", yearDayName, hour, min);
                                            time = fopen(timeName, "a+");
                                            fprintf(time, "%s\t", extractedStation);
                                            fprintf(time, "%f\t", coordinates[0]);
                                            fprintf(time, "%f\t", coordinates[1]);
                                            fprintf(time, "%f\t", coordinates[2]);
                                            fprintf(time, "%s\t", rms);
                                            fprintf(time, "%f\n", delay);
                                            fclose(yearDay);
                                        }
[.....]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

長街聽風 2024-12-12 05:37:04

您没有向我们展示足够多的内容,因此这纯粹是猜测,但是您正在读取到 extractedHour 的输入可能是三个字符长,并且您已将数组定义为 3 个字符,没有留下任何空间对于 NUL 终止符。

您可能在 extractedHour 之后立即定义了 min,因此当您写入超过 extractedHour 末尾时,最终会将 NUL 终止符写入下一个内存,恰好是 min

You haven't shown us enough, so it's purely a guess, but the input you're reading into extractedHour is probably three characters long, and you've defined the array as 3 characters, leaving no room for the NUL terminator.

You've probably defined min immediately after extractedHour, so when you write past the end of extractedHour, it ends up writing the NUL terminator into the next memory, which happens to be min.

打小就很酷 2024-12-12 05:37:04

如果没有更多信息,我的猜测是 locDayFile 包含一个超过 3 个字节的字符串。当您进行 fscanf 调用时,它会覆盖比您想象的更多的内存。尝试为extractHour分配一个更大的缓冲区(而不是3,使它像64)并让我们知道会发生什么。如果这解决了问题,您可能需要首先修复 locDayFile,然后修复 fscanf 调用,而不是使用 %s,而是使用 %2s,这告诉 scanf (及其变体)您只希望它读取带有最多 2 个字符。这将避免缓冲区溢出。另一种选择是使用 %as... 用于分配字符串(scanf 将分配存储字符串所需的字节数)。

示例:

char *str;
fscanf(in_file, "%as", &str);  //Notice the & here!
//Not covered is calling free(str)
//But you must check if fscanf was successful
//before freeing str

示例 2:

char str[3];
fscanf(in_file, "%2s", str);  //Notice this doesn't use &
//No need to deallocate, and it will not buffer overrun on you!

如果这不能修复您的程序,请向我们提供更多信息。

Without a bit more information, my guess is locDayFile contains a string that is more than 3 bytes. When you make your fscanf call, it overwrites more memory than you think it should. Try allocating a larger buffer to extractedHour (instead of 3, make it like 64) and let us know what happens. If that fixes the problem, you might need to first fix your locDayFile, then fix your fscanf call, rather than using %s, use %2s, this tells scanf (and it's variants) that you only want it to read a string with a maximum # of 2 characters. This will avoid a buffer over-run. Another option, is to use %as... which is used to allocate a string (scanf will allocate however many bytes it needs to store the string).

Example:

char *str;
fscanf(in_file, "%as", &str);  //Notice the & here!
//Not covered is calling free(str)
//But you must check if fscanf was successful
//before freeing str

Example 2:

char str[3];
fscanf(in_file, "%2s", str);  //Notice this doesn't use &
//No need to deallocate, and it will not buffer overrun on you!

If this doesn't fix your program, give us a bit more info.

水晶透心 2024-12-12 05:37:04

抱歉,我只能给出风格上的评论。

1)分而治之:将代码分成逻辑函数,每个函数只做一件事情。这也将使测试单独的部件变得更容易,而不会受到太多干扰。

2) feof() 并没有像你想象的那样做。

3)如果您首先读取整行(例如使用 fgets())然后将它们拆分为字段,则解析文本文件会更容易。它也不易受到缓冲区溢出的影响。

4) gets() 会带来灾难。 scanf() 的形式也是如此。

Sorry, I can only give stylistic remarks.

1) divide and conquer: split the code up into logical functions, each doing only one thing. This will also make it easier to test the separate parts without too much interference.

2) feof() does not do what you think it does.

3) Parsing text files is easier if you first read in entire lines (eg with fgets()) and than split them up into fields. It is also less vulnerable to bufferoverflow.

4) gets() is a recipe for disaster. So is scanf() in the form you are using it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文