为什么我的琴弦获得了一些额外的价值? (C程序)

时间:2018-08-11 17:20:27

标签: c algorithm

我正在尝试解决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@多了。我不要那多余的东西。但我无法解决。如果有人可以帮助我修复它,那就太好了。

3 个答案:

答案 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];

将解决此问题。