如何存储以某些字符结尾的字符串?

时间:2017-06-21 21:51:45

标签: c

我想创建一个程序,打开并写入3个不同的文本文件,即用户输入的名称。

条件是如果姓氏以某些字符结尾,则会将其保存到特定的文本文件中。

例如,如果用户输入以ian结尾的姓氏,则应将其保存到ARMENIA.TXT文件夹。

这是我的代码以及我遇到的问题:

struct names {
    char firstName[20];
    char lastName[30];
} person;

int main() {
    FILE *arm, *ita, *esp;
    char ian[] = "ian";
    char ini[] = "ini";
    char ez[] = "ez";
    char response;
    char *ret;

    arm = fopen("C:\\Programming\\ARMENIA.TXT", "wt");
    ita = fopen("C:\\Programming\\ITALIA.TXT", "wt");
    esp = fopen("C:\\Programming\\ESPANIA.TXT", "wt");

    if (arm, ita, esp == NULL) {
        printf("Error: The archives could not be created.");
        return 1;
    } else {
        printf("Operation Successful: Archives created.\n\n");
    }

    do {
        fflush(stdin);
        printf("\n\nPlease input your first name: ");
        scanf("%s", &person.firstName);
        printf("Please input your last name: ");
        scanf("%s", &person.lastName);

        if (ret = strstr(person.lastName, ian)) {  
            fwrite(person.lastName, 1, strlen(person.lastName), arm);
            fwrite(person.firstName, 1, strlen(person.firstName), arm);
        }

        if (ret = strstr(person.lastName, ini)) { 
            fwrite(person.lastName, 1, strlen(person.lastName), ini);
            fwrite(person.firstName, 1, strlen(person.firstName), ini);
        }

        if (ret = strstr(person.lastName, ez)) { 
            fwrite(person.lastName, 1, strlen(person.lastName), ez);
            fwrite(person.firstName, 1, strlen(person.firstName), ez);
        }

        printf("\n\nWould you like to enter another person into the archive?: (y) or (n): ");
        scanf(" %c", &response);

    } while (response == 'y');

    printf("\n\nThe operation has finished.\n\n");

    fclose(arm);
    fclose(ita);
    fclose(esp);

    return 0;
}

问题:如果姓氏在姓氏的任何部分包含ian(或ini / ez),将保存到文件夹。如果条件ENDS与这些字符串一起使用,我该怎么做?

问题:如果姓氏包含iniez,则会崩溃 - 基本上,只有第一个If语句有效。

问题:需要保存为姓氏,名字 - 现在,它保存为LastnameFirstname。

3 个答案:

答案 0 :(得分:1)

这里有许多不相关的问题。

arm = fopen("C:\\Programming\\ARMENIA.TXT", "wt");

那应该是" w +"而不是" wt"。其他人也一样。或者只是" w",除非你想要读写。

if (arm, ita, esp == NULL)

逗号运算符计算其左操作数并将其丢弃,然后计算其右操作数并保留该值。所以这相当于if (esp == NULL)

fflush(stdin);

这没有意义。打印时,允许系统缓冲输出,然后立即打印输出,这可以加快速度。 fflush强制它实际打印当前在缓冲区中的任何内容。例如,如果您想要提示用户输入并且需要确保提示出现,那么它很有用。

因此,它仅适用于输出流。 (这个错误实际上是在一些可怕的参考资料中讲授的,所以我怀疑这个错误不是你的错。你应该停止使用告诉你的任何参考文件。)

附录:正如奥拉夫在评论中指出的那样,这会引发未定义的行为,这本身就是一个话题。简短且不精确的版本是任何未定义的行为都会产生很难追踪的错误。

if (ret = strstr(person.lastName, ian)) 

这告诉你,ian在某个地方是人物。在某个地方,但不是它在最后。例如,假设姓氏是" ian in ez"。它符合您的所有三个条件。顺便说一句,你不需要将ian存储在一个变量中;你可以做strstr(person.lastName, "ian")

答案 1 :(得分:1)

除了Ray指出的问题之外,请参阅以下strEndsWith函数的简单代码。希望它有所帮助。

int strEndsWith(const char* str, const char* ending) {
    size_t strlenStr = strlen(str);
    size_t strlenEnding = strlen(ending);
    if (strlenStr < strlenEnding)
        return 0;

    const char* strAtEnding = str + strlenStr - strlenEnding;

    return (strcmp(strAtEnding, ending) == 0);
}

答案 2 :(得分:1)

您的计划有多个问题。

Ray和Stephen Lechner已经解决了一些问题,但是还有一些问题:

  • 崩溃的原因是您将字符串传递给fwrite而不是FILE*流指针:fwrite(person.lastName, 1, strlen(person.lastName), ini);应写入:

    fwrite(person.lastName, 1, strlen(person.lastName), ita);
    

    这表示您在未启用适当警告的情况下进行编译。让编译器帮助避免-Wall的{​​{1}}或gcc的{​​{1}}这样的愚蠢错误。

  • 另请注意,您应使用/W3正确格式化文本文件的输出。例如:

    msvc

以下是改进版本:

fprintf