C 从一个文件中读取数据并写入另一个文件
C Reading data from one file and writing it into another file
问题:
我有一个正在处理的项目,它与二进制搜索树和文件 input/output 一起工作。二叉搜索树似乎运行正常,但是其中一个要求是能够通过文件输入将数据添加到二叉树(然后输出所有二叉树数据)。我使用 fgets+sscanf 方法查看文件,它似乎正确地抓取了所有项目,但字符串发生了巨大的变化。我怀疑这是一个空终止符问题,但无法确定我可以修复它的确切位置。当我手动(而不是从文件)将节点添加到二叉树时,它们会毫无问题地添加,并且毫无问题地写入新的文本文件。唯一的问题来自于从文件中读取数据,这会抛出一些奇怪的错误来修改我的数据(例如字符串以 é@—Ç 等奇怪的格式出现,而不是 FirstName1 LastName1 的预期输出)。
也很抱歉,我对C还是比较陌生,所以可能会显得有点乱。
我的(徒劳的)尝试:
如以下代码所述,我尝试手动向字符串添加空终止符,因为我认为这是问题所在。我尝试更改文件内容并在那里添加空终止符,并且我也尝试使用 fscanf 方法来读取文件。我研究了其他 Whosebug 页面,寻找我可能遗漏的东西,但我什么也没找到。我确定我忽略了一些愚蠢的事情。
我的文本文件:
同样,以下这些文本文件内容仅与从文件中添加的内容有关。我通过使用字符串文字调用 addNode 函数手动添加的任何内容都没有问题
我尝试添加学生的 'input' 文本文件(又名 addFile 在我的测试中使用):
400085 FirstName1 LastName1 3.88 CompSci
400076 FirstName2 LastName2 2.77 LibertyArts
我的 'output' writeFile 使用的文本文件:
400085 é@—Ç 3.880000 ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
400076 é@—Ç 2.770000 ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
代码:
添加文件
取一个字符串名称,找到文件,并打开它的内容
void addFile(char* name) {
FILE* myFile = fopen(name, "r");
if (myFile == NULL) {
perror(name);
return;
}
int tempId = 0;
char firstName[100];
char lastName[100];
double GPA = 0.0;
char major[100];
int res = 0;
char line[10000];
while (fgets(line, 1000, myFile) != NULL) {
res = sscanf(line, "%d %s %s %lf %s", &tempId, firstName, lastName, &GPA, major);
firstName[99] = '[=12=]';
lastName[99] = '[=12=]';
major[99] = '[=12=]';
addNode(tempId, firstName, lastName, GPA, major);
}
fclose(myFile);
}
写入文件
写入文本文件,testFile.txt 二叉搜索树的内容
void preorder(struct Node* nodeAt) {
char buffer[10000];
snprintf(buffer, sizeof(buffer), "%d %s %s %lf %s \n", nodeAt->id, nodeAt->firstName, nodeAt->lastName, nodeAt->GPA, nodeAt->major);
strcat(tempString, buffer);
if (nodeAt->leftChild != NULL)
preorder(nodeAt->leftChild);
if (nodeAt->rightChild != NULL)
preorder(nodeAt->rightChild);
}
void writeFile() {
FILE* fp = fopen("testFile.txt", "w");
tempString = (char*) malloc(sizeof(char*) * 10000);
preorder(root);
fprintf(fp, "%s", tempString);
free(tempString);
tempString = "";
}
addFile调用的其他相关函数
/*
createNode() method
"safe" way of creating the node. Also cleans up the code.
*/
struct Node* createNode(int id, char* firstName, char* lastName, double GPA, char* major) {
struct Node* myNode = (struct Node*) malloc(sizeof(struct Node));
if (myNode != NULL) {
myNode->id = id;
myNode->firstName = firstName;
myNode->lastName = lastName;
myNode->GPA = GPA;
myNode->major = major;
myNode->rightChild = NULL;
myNode->leftChild = NULL;
myNode->parent = NULL;
return myNode;
}
else
return NULL;
}
/*
addNode() + addNodeHelper() methods
Adds a node to the binary tree. The helper method is just recursive to make searching easier
*/
struct Node* addNodeHelper(struct Node* nodeAt, int id, struct Node* nodeToAdd) {
struct Node* temp = nodeAt;
if (temp->leftChild == NULL && id < temp->id) {
nodeAt->leftChild = nodeToAdd;
nodeAt->leftChild->parent = nodeAt;
}
else if (temp->rightChild == NULL && id > temp->id) {
nodeAt->rightChild = nodeToAdd;
nodeAt->rightChild->parent = nodeAt;
}
if (id < temp->id)
addNodeHelper(temp->leftChild, id, nodeToAdd);
else if (id > temp->id)
addNodeHelper(temp->rightChild, id, nodeToAdd);
}
void addNode(int id, char* firstName, char* lastName, double GPA, char* major) {
struct Node* myNode = createNode(id, firstName, lastName, GPA, major);
if (myNode != NULL) {
struct Node* findTheNode = findNode(root, myNode->id);
if (root == NULL) {
root = myNode;
return;
}
if (findTheNode != NULL) {
printf("ERROR: Student ID must be unique!\n");
return;
} else
addNodeHelper(root, myNode->id, myNode);
}
}
非常感谢任何 hints/recommendations :)
createNode
只是保存指向它给出的字符串的指针。 addFile
每次循环都会覆盖相同的字符串,因此每个节点都有相同的指针。此外,这些是局部变量,因此指针在 addFile
returns.
之后变得无效
您需要复制字符串。
addNode(tempId, strdup(firstName), strdup(lastName), GPA, strdup(major));
问题:
我有一个正在处理的项目,它与二进制搜索树和文件 input/output 一起工作。二叉搜索树似乎运行正常,但是其中一个要求是能够通过文件输入将数据添加到二叉树(然后输出所有二叉树数据)。我使用 fgets+sscanf 方法查看文件,它似乎正确地抓取了所有项目,但字符串发生了巨大的变化。我怀疑这是一个空终止符问题,但无法确定我可以修复它的确切位置。当我手动(而不是从文件)将节点添加到二叉树时,它们会毫无问题地添加,并且毫无问题地写入新的文本文件。唯一的问题来自于从文件中读取数据,这会抛出一些奇怪的错误来修改我的数据(例如字符串以 é@—Ç 等奇怪的格式出现,而不是 FirstName1 LastName1 的预期输出)。
也很抱歉,我对C还是比较陌生,所以可能会显得有点乱。
我的(徒劳的)尝试:
如以下代码所述,我尝试手动向字符串添加空终止符,因为我认为这是问题所在。我尝试更改文件内容并在那里添加空终止符,并且我也尝试使用 fscanf 方法来读取文件。我研究了其他 Whosebug 页面,寻找我可能遗漏的东西,但我什么也没找到。我确定我忽略了一些愚蠢的事情。
我的文本文件:
同样,以下这些文本文件内容仅与从文件中添加的内容有关。我通过使用字符串文字调用 addNode 函数手动添加的任何内容都没有问题
我尝试添加学生的 'input' 文本文件(又名 addFile 在我的测试中使用):
400085 FirstName1 LastName1 3.88 CompSci
400076 FirstName2 LastName2 2.77 LibertyArts
我的 'output' writeFile 使用的文本文件:
400085 é@—Ç 3.880000 ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
400076 é@—Ç 2.770000 ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
代码:
添加文件 取一个字符串名称,找到文件,并打开它的内容
void addFile(char* name) {
FILE* myFile = fopen(name, "r");
if (myFile == NULL) {
perror(name);
return;
}
int tempId = 0;
char firstName[100];
char lastName[100];
double GPA = 0.0;
char major[100];
int res = 0;
char line[10000];
while (fgets(line, 1000, myFile) != NULL) {
res = sscanf(line, "%d %s %s %lf %s", &tempId, firstName, lastName, &GPA, major);
firstName[99] = '[=12=]';
lastName[99] = '[=12=]';
major[99] = '[=12=]';
addNode(tempId, firstName, lastName, GPA, major);
}
fclose(myFile);
}
写入文件 写入文本文件,testFile.txt 二叉搜索树的内容
void preorder(struct Node* nodeAt) {
char buffer[10000];
snprintf(buffer, sizeof(buffer), "%d %s %s %lf %s \n", nodeAt->id, nodeAt->firstName, nodeAt->lastName, nodeAt->GPA, nodeAt->major);
strcat(tempString, buffer);
if (nodeAt->leftChild != NULL)
preorder(nodeAt->leftChild);
if (nodeAt->rightChild != NULL)
preorder(nodeAt->rightChild);
}
void writeFile() {
FILE* fp = fopen("testFile.txt", "w");
tempString = (char*) malloc(sizeof(char*) * 10000);
preorder(root);
fprintf(fp, "%s", tempString);
free(tempString);
tempString = "";
}
addFile调用的其他相关函数
/*
createNode() method
"safe" way of creating the node. Also cleans up the code.
*/
struct Node* createNode(int id, char* firstName, char* lastName, double GPA, char* major) {
struct Node* myNode = (struct Node*) malloc(sizeof(struct Node));
if (myNode != NULL) {
myNode->id = id;
myNode->firstName = firstName;
myNode->lastName = lastName;
myNode->GPA = GPA;
myNode->major = major;
myNode->rightChild = NULL;
myNode->leftChild = NULL;
myNode->parent = NULL;
return myNode;
}
else
return NULL;
}
/*
addNode() + addNodeHelper() methods
Adds a node to the binary tree. The helper method is just recursive to make searching easier
*/
struct Node* addNodeHelper(struct Node* nodeAt, int id, struct Node* nodeToAdd) {
struct Node* temp = nodeAt;
if (temp->leftChild == NULL && id < temp->id) {
nodeAt->leftChild = nodeToAdd;
nodeAt->leftChild->parent = nodeAt;
}
else if (temp->rightChild == NULL && id > temp->id) {
nodeAt->rightChild = nodeToAdd;
nodeAt->rightChild->parent = nodeAt;
}
if (id < temp->id)
addNodeHelper(temp->leftChild, id, nodeToAdd);
else if (id > temp->id)
addNodeHelper(temp->rightChild, id, nodeToAdd);
}
void addNode(int id, char* firstName, char* lastName, double GPA, char* major) {
struct Node* myNode = createNode(id, firstName, lastName, GPA, major);
if (myNode != NULL) {
struct Node* findTheNode = findNode(root, myNode->id);
if (root == NULL) {
root = myNode;
return;
}
if (findTheNode != NULL) {
printf("ERROR: Student ID must be unique!\n");
return;
} else
addNodeHelper(root, myNode->id, myNode);
}
}
非常感谢任何 hints/recommendations :)
createNode
只是保存指向它给出的字符串的指针。 addFile
每次循环都会覆盖相同的字符串,因此每个节点都有相同的指针。此外,这些是局部变量,因此指针在 addFile
returns.
您需要复制字符串。
addNode(tempId, strdup(firstName), strdup(lastName), GPA, strdup(major));