我正在尝试解决C程序问题:
用C语言创建一个程序,该程序从文本文件中读取字符串,然后以奇偶格式对字符串重新排序(首先采用奇数字母,然后采用偶数字母;例如:如果程序读取elephant
,则重新排序的字符串将为eehnlpat
)。然后将字符串写入另一个文本文件。提供用于读取和写入的错误检查机制。
我的代码是:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
FILE *inputFile;
inputFile = fopen("inpFile.txt", "r");
if (inputFile != NULL) {
FILE *outFile = fopen("outFile.txt", "w");
if (outFile != NULL) {
printf("file created successfully\n");
int i, j = 0;
char strf1[50];
fscanf(inputFile, "%s", &strf1);
char strf2[strlen(strf1)];
for (i = 0; strf1[i] > 0; i++) {
if (i % 2 == 0) {
strf2[j] = strf1[i];
j++;
}
}
for (i = 1; strf1[i] > 0; i++) {
if (i % 2 == 1) {
strf2[j] = strf1[i];
j++;
}
}
fprintf(outFile, "%s\n", strf2);
fclose(outFile);
} else {
printf("file could not be created\n");
}
fclose(inputFile);
} else {
printf("File does not exist.");
}
return 0;
}
我觉得一切都很好,但是问题是,如果程序读取elephant
,那么我的程序给出的重新排序的字符串就是eehnlpatZ0@
。我的问题出在哪里Z0@
多了。我不要那多余的东西。但我无法解决。如果有人可以帮助我修复它,那就太好了。
答案 0 :(得分:3)
您的目标字符串太短:char strf2[strlen(strf1)];
。您至少应允许使用空终止符并进行设置,或者仅使输出数组与输入数组具有相同的大小:
char strf2[50];
您的代码中还有其他问题:
如果fopen
错误,建议将非零状态返回给系统。
您应该将数组传递给fscanf()
,而不是指向具有不同类型的数组的指针。
您应该使用fscanf()
告诉%49s
读取到数组中的最大字符数
您应该测试fscanf()
的返回值,并为空的输入文件生成一个空的输出文件。在这种情况下,当前代码具有未定义的行为。
测试strf1[i] > 0
不正确:输入文件中的字符可能为负。您应该计算字符串长度或使用strf1[i] != '\0'
从i = 1
开始第二个循环似乎是个好主意,但是它基于strf1
不是空字符串的无声假设。在您的示例中,如果fscanf()
成功,则strf1
不为空,如果失败,则行为是不确定的,因为strf1
未初始化。但是,避免这样的优化会更安全,因为如果您以后将代码移至假设可能不成立的通用函数,则会对您造成困扰。
在将输出字符串传递给fprintf
或以%.*s
格式指定长度之前,必须先终止输出字符串。
这是更正的版本:
#include <stdio.h>
int main() {
FILE *inputFile, *outFile;
char strf1[50], strf2[50];
int i, j;
inputFile = fopen("inpFile.txt", "r");
if (inputFile == NULL) {
printf("Cannot open input file inpFile.txt\n");
return 1;
}
outFile = fopen("outFile.txt", "w");
if (outFile == NULL) {
printf("Could not create output file outFile.txt\n");
fclose(inputFile);
return 1;
}
printf("file created successfully\n");
if (fscanf(inputFile, "%49s", strf1) == 1) {
j = 0;
for (i = 0; strf1[i] != '\0'; i++) {
if (i % 2 == 0)
strf2[j++] = strf1[i];
}
for (i = 0; strf1[i] != '\0'; i++) {
if (i % 2 == 1)
strf2[j++] = strf1[i];
}
strf2[j] = '\0';
fprintf(outFile, "%s\n", strf2);
}
fclose(inputFile);
fclose(outFile);
return 0;
}
这里是使用更简单的复制循环的替代方法:
int len = strlen(strf1);
j = 0;
for (i = 0; i < len; i += 2) {
strf2[j++] = strf1[i];
}
for (i = 1; i < len; i += 2) {
strf2[j++] = strf1[i];
}
strf2[j] = '\0';
答案 1 :(得分:0)
您必须为null终止符提供一个空格,因为您没有为其提供空格,printf
无法知道字符串何时终止,因此它将继续从内存中打印出数据。 / p>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE* inputFile;
inputFile=fopen("inpFile.txt", "r");
if (inputFile!=NULL) {
FILE* outFile=fopen("outFile.txt", "w");
if (outFile!=NULL) {
printf("file created successfully\n");
int i, j=0;
char strf1[50];
fscanf(inputFile, "%s",&strf1);
int inputLength = strlen(strf1) + 1;
char strf2[inputLength];
char strf2[inputLength-1] = '\0';
for(i=0; strf1[i]>0; i++) {
if(i%2==0) {
strf2[j]=strf1[i];
j++;
}
}
for(i=1; strf1[i]>0; i++) {
if(i%2==1) {
strf2[j]=strf1[i];
j++;
}
}
fprintf(outFile, "%s\n",strf2);
fclose(outFile);
}else{
printf("file could not be created\n");
}
fclose(inputFile);
}
else {
printf("File does not exist.");
}
return 0;
}
答案 2 :(得分:0)
在C语言中,字符串要求以空字符'\ 0'作为最后一个字节才能终止。
更改以下代码行
char strf2[strlen(strf1)];
到
char strf2[strlen(strf1) + 1];
将解决此问题。