调用 fscanf 时数组更改第一个值而不显式修改它
我正在从 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您没有向我们展示足够多的内容,因此这纯粹是猜测,但是您正在读取到
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 afterextractedHour
, so when you write past the end ofextractedHour
, it ends up writing the NUL terminator into the next memory, which happens to bemin
.如果没有更多信息,我的猜测是 locDayFile 包含一个超过 3 个字节的字符串。当您进行 fscanf 调用时,它会覆盖比您想象的更多的内存。尝试为extractHour分配一个更大的缓冲区(而不是3,使它像64)并让我们知道会发生什么。如果这解决了问题,您可能需要首先修复 locDayFile,然后修复 fscanf 调用,而不是使用 %s,而是使用 %2s,这告诉 scanf (及其变体)您只希望它读取带有最多 2 个字符。这将避免缓冲区溢出。另一种选择是使用 %as... 用于分配字符串(scanf 将分配存储字符串所需的字节数)。
示例:
示例 2:
如果这不能修复您的程序,请向我们提供更多信息。
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:
Example 2:
If this doesn't fix your program, give us a bit more info.
抱歉,我只能给出风格上的评论。
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.