简体   繁体   English

不断获取简单C程序的运行时错误

[英]Keep getting runtime error for simple C program

I have to write a program that checks whether the string is a palindrome or not. 我必须编写一个程序来检查字符串是否是回文。 A palindrome is a sequence which is the same forwards as backwards. 回文是顺序相同的向前和向后。 For example, kayak is a palindrome, canoe is not a palindrome, hannah is a palindrome, etc. 例如,皮艇是回文,独木舟不是回文,汉娜是回文,等等。

Here is my code so far: 到目前为止,这是我的代码:

#include <stdio.h>
#include <string.h>

#define MAX_CHAR 4096

int main(void) {

    printf("Enter a string: ");

    char line[MAX_CHAR] = {0};

    fgets(line, MAX_CHAR, stdin);

    int length = strlen(line) - 1;

    int i = 0;
    int j = length - 1;

    char line2[length];
    while (i < length){
        if (j >= 0){
            line2[i] = line[j];
        }
        i++;
        j--;
    }

    if (strcmp(line, line2) != 0){
        printf("String is not a palindrome\n");
    } else if (strcmp(line, line2) == 0) {
        printf("String is a palindrome\n");
    }

    return 0;
}

This works for non-palindromes but each time I test with a palindrome, I am getting a runtime error as shown in the image . 这适用于非回文但每次我回文考试的时候,我得到一个运行时错误,如图所示的图像 How do I solve this? 我该如何解决?

The issue you are facing is caused by the fact that you do not add a null terminator to line2 (and the array also doesn't have enough space for one), therefore line2 is not a null-terminated byte string. 你面临的问题是事实,你没有一个空终止添加造成line2 (和阵列还没有一个足够的空间),因此line2是不是空终止字节串。

Passing a pointer to anything other than a null-terminated byte string to strcmp invokes undefined behavior 将指针传递给strcmp空终止的字节字符串以外的其他任何字符串以传递给strcmp调用未定义的行为

The simplest way to fix your code is to make the following changes: 修改代码的最简单方法是进行以下更改:

/* Don't subtract 1 from `strlen`, otherwise you don't copy the entire string in your loop */
int length = strlen(line);
/* Unchanged */
int i = 0;
int j = length - 1;
/* increase size of array by 1 to have space for null-terminator */
char line2[length + 1];
/* Loop is unchanged */
while (i < length){
    if (j >= 0){
        line2[i] = line[j];
    }
    i++;
    j--;
}
/* Add null-terminator to have a valid byte string */
line2[length] = '\0'; 

Please also note that there are simpler ways to achieve the palindrome check, but this answer only focuses on why your code runs into the runtime error. 还请注意,有多种简单的方法可以实现回文检查,但是此答案仅着重于代码为什么会遇到运行时错误的原因。

EDIT: As pointed out in the comments fgets also stores the newline character inside the array. 编辑:正如注释中指出的, fgets还将换行符存储在数组中。 In order for your palindrome check to work correctly you need to adjust your code (eg: removing the newline from line before creating line2 and copying the characters) 为了使回文检查正常工作,您需要调整代码(例如:在创建第line2 line之前从line删除换行符并复制字符)

Easier way: 更简单的方法:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int palindrome(const char *word)
{
    size_t len = strlen(word);  
    const char *end = word + len -1;
    len >>= 1;
    while(len--)
    {
        if(*word++ != *end--)
            return 1;  //not
    }
    return 0; //yes;
}

int main()
{
printf("%s\n", palindrome("kayak") ? "No" : "Yes");

}

You have wrong bounds checking, and also fgets reads newline which you have to delete. 您的边界检查错误,并且fgets读取必须删除的换行符。 This is the only compete answer which also check if string entered is not empty: 这是唯一竞争的答案,它还会检查输入的字符串是否不为空:

#include <string.h>

#define MAX_CHAR 4096

int main(void) {

    printf("Enter a string: ");

    char line[MAX_CHAR] = {0};

    fgets(line, MAX_CHAR, stdin);
    //remove new line
    int length = strlen(line);
    if (length > 0) {
        line[length-1] = '\0';
    }

    //update length
    length = strlen(line);
    if (!length) {
        printf("String is empty\n");
        return 1;
    }

    int i = 0;
    int j = length - 1;

    char line2[length+1];

    while (i < length){
        line2[i++] = line[j--];
    }

    //Add 0 char
    line2[i] = '\0';
    if (strcmp(line, line2) != 0){
        printf("String is not a palindrome\n");
    } else if (strcmp(line, line2) == 0) {
        printf("String is a palindrome\n");
    }


  return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM