[英]Why my fputs doesn't work when the file already contains anything?
我尝试向已经包含一些文本的现有文件添加新行。 我发现当文件包含某些内容时,程序在 fputs(stringToAdd, myFile) 之后停止工作; 在 function void Save(struct SEED arrayToSave[], int size)。 但是,当我尝试写入一个空文件时,一切正常。 你们能帮帮我吗?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int numberOfItems = 0;
char path[] = "Catalogue.txt";
char text[1000000];
struct SEED {
int index;
char type[30];
char name[60];
float mass;
float price;
};
void GetText() {
FILE* catalogueFile;
char ch; // temporary char
int counter = 0;
catalogueFile = fopen(path, "r");
while((ch = fgetc(catalogueFile)) != EOF ) {
text[counter] = ch;
counter++;
}
fclose(catalogueFile);
}
void CalculateNumberOfItems() {
for(int i = 0; i < strlen(text); i++) {
if(text[i] == '\n') numberOfItems++;
}
}
struct SEED* GetArrayOfStructs() {
GetText();
CalculateNumberOfItems();
FILE* catalogueFile;
int counter = 0;
char* arrayOfSubstrings[numberOfItems];
struct SEED* arrayOfStructs = malloc(numberOfItems * sizeof(arrayOfStructs));
struct SEED* arrayOfStructsPointer = arrayOfStructs;
char* token = strtok(text, "\n");
while( token != NULL ) {
arrayOfSubstrings[counter] = token;
token = strtok(NULL, "\n");
counter++;
}
for(int i = 0; i < numberOfItems; i++) {
struct SEED tempStruct;
sscanf(arrayOfSubstrings[i], "%d %s %s %f %f", &tempStruct.index, tempStruct.type, tempStruct.name, &tempStruct.mass, &tempStruct.price);
arrayOfStructs[i] = tempStruct;
}
return arrayOfStructsPointer;
}
void Save(struct SEED arrayToSave[], int size) {
FILE* myFile = fopen("Catalogue.txt", "w");
char fullString[1000000];
for(int i = 0; i < size; i++) {
struct SEED currentStruct = arrayToSave[i];
char stringToAdd[1000];
sprintf(stringToAdd, "%d %s %s %f %f\n", currentStruct.index, currentStruct.type, currentStruct.name, currentStruct.mass, currentStruct.price);
strcat(fullString, stringToAdd);
}
printf("%s\n", fullString);
fputs(fullString, myFile);
fclose(myFile);
}
void AddNew() {
struct SEED* oldArrayOfStructs = GetArrayOfStructs(path);
struct SEED newArrayOfStructs[numberOfItems + 1];
struct SEED newStruct;
int newIndex = numberOfItems + 1;
char newType[30], newName[60];
float newMass, newPrice;
char tempChar[200];
printf("Input type, name, mass and price\nof the new seed whith spaces: ");
fgets(tempChar, 200, stdin);
fgets(tempChar, 200, stdin);
sscanf(tempChar, "%s %s %f %f\\n", newType, newName, &newMass, &newPrice);
newStruct.index = newIndex;
strcpy(newStruct.type, newType);
strcpy(newStruct.name, newName);
newStruct.mass = newMass;
newStruct.price = newPrice;
printf("%d\n", numberOfItems);
for(int i = 0; i < numberOfItems; i++) {
newArrayOfStructs[i] = oldArrayOfStructs[i];
}
newArrayOfStructs[numberOfItems] = newStruct;
Save(newArrayOfStructs, numberOfItems + 1);
printf("\n");
}
void UserInput() {
char choice;
int choiceInt, a = 1;
printf("Add new item - print 1\n");
printf("\n");
printf("Input your choice: ");
choice = getchar();
choiceInt = choice - '0';
printf("\n");
switch(choiceInt) {
case 1:
AddNew();
break;
default:
printf("Bye!\n");
break;
}
}
int main() {
UserInput();
return 0;
}
至少这些问题:
分配太小
代码错误地分配了一个指针数组。
// struct SEED* arrayOfStructs = malloc(numberOfItems * sizeof(arrayOfStructs));
struct SEED* arrayOfStructs = malloc(numberOfItems * sizeof arrayOfStructs[0]);
char
太小,无法区分来自fgetc()
的 257 个不同响应
// char ch; // temporary char
int ch;
...
while((ch = fgetc(catalogueFile)) != EOF ) {
潜在的缓冲区溢出
使用宽度。
使用"\\n"
扫描 2 个字符\
和n
毫无意义。
// sscanf(tempChar, "%s %s %f %f\\n", newType, newName, &newMass, &newPrice);
sscanf(tempChar, "%29s %59s %f %f", newType, newName, &newMass, &newPrice);
最好也测试sscanf()
结果。
if (sscanf(tempChar, "%29s %59s %f %f", newType, newName, &newMass, &newPrice) != 4) {
TBD_error_code();
}
溢出风险
// while((ch = fgetc(catalogueFile)) != EOF ) {
while(counter < (sizeof text - 1) && (ch = fgetc(catalogueFile)) != EOF ) {
text[counter] = ch;
可能溢出风险
// sprintf(stringToAdd, "%d %s %s %f %f\n",
snprintf(stringToAdd, sizeof stringToAdd, "%d %s %s %f %f\n",
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.