奇怪的字符输出在倒计时算法与超过4字符输入

时间:2023-01-05 23:12:21

I'm trying to take an input string like 12340 and output 4321. The weird thing is, if I put a sequence that is smaller than 4 (ex : 1230), the output is correct (321). But if I input 12340, I end up having 4321(↨@. What causes this behavior?

我尝试取一个输入字符串,比如12340和输出4321。奇怪的是,如果我放一个小于4的序列(例如:1230),输出是正确的(321)。但是如果我输入12340,我有4321(↨@。导致这种行为的原因是什么?

(This is no homework, I'm following exercice 6.8 of http://www.ltam.lu/cours-c/prg-c58.htm to learn C)

(这不是家庭作业,我是按照http://www.ltam.lu/cours-c/prg-c58.htm的努力6.8学习C)

Here is my whole code (I would post a small/concise code example but I can't seem to put the finger on the problem)

这是我的全部代码(我将发布一个小型/简洁的代码示例,但我似乎无法指出问题的症结所在)

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

int main()
{
    char array[100];

    printf("Shoot me consecutive numbers, end with 0\n");
    scanf("%s",&array);
    int count = strlen(array);
    char countdown[count];
    int reverseIndex;
    int index = 0;
    for(reverseIndex = count-1;reverseIndex >= 0;reverseIndex--)
    {
        char possibleNumber = array[reverseIndex];
        if(isdigit(possibleNumber) && possibleNumber != '0')
        {
            countdown[index] = possibleNumber;
            index++;
        }
    }
    printf("countdown : %s\n",countdown);
    return 0;
}

2 个解决方案

#1


2  

One immediate error is this line:

一个直接的错误是:

you need to provide enough room for the NULL terminator in this line:

您需要为这一行的空终止符提供足够的空间:

char countdown[count + 1];//added +1  

Another is:

另一个原因是:

scanf("%s",&array);  

Change it to:

把它改成:

scanf("%s",array); //%s expects char *, &array is of type char (*)[100], parameter type mismatch 

I made these edits to the original code (see in-line comments), also used call to memset() to initialize countdown, and it runs: (results shown below)

我对原始代码进行了这些编辑(请参阅内联注释),还使用对memset()的调用来初始化倒计时,它运行:(结果如下所示)

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

int main()
{
    char array[100];

    printf("Shoot me consecutive numbers, end with 0\n");
    scanf("%s",array);//removed &
    int count = strlen(array);
    char countdown[count+1];//add room for NULL terminator
    int reverseIndex;
    int index = 0;
    memset(countdown, 0, count+1);//added to initialize all elements of char array to NULL
    for(reverseIndex = count-1;reverseIndex >= 0;reverseIndex--)
    {
        char possibleNumber = array[reverseIndex];
        if(isdigit(possibleNumber) && possibleNumber != '0')
        {
            countdown[index] = possibleNumber;
            index++;
        }
    }
    printf("countdown : %s\n",countdown);

    getchar();
    getchar();
    return 0;
}

Input and output:

输入和输出:

奇怪的字符输出在倒计时算法与超过4字符输入

EDIT to answer comment question about undesired characters in result
(and original question: ...But if I input 12340, I end up having 4321(↨@... )

编辑以回答关于结果中不希望出现的字符的评论问题(以及原始问题:……)但是如果我输入12340,我有4321(↨@……)

When char countdown[count+1]; is created, there is no guarantee of the contents.
That is, each position can be filled with any random set of bits.
Say array is defined as char array[5]; If not initialized, it may look like this in memory:

当char倒计时(数+ 1);是创建的,没有内容的保证。也就是说,每个位置都可以包含任意一组比特。设数组定义为char数组[5];如果没有初始化,在内存中可能是这样的:

|€|Œ|™|¢|§|  

Later in your code, you loop through to make assignments to each position to
populate with characters obtained using `scanf() from stdin, which is fine,
Now, it looks like this after looping 4 times:

在您的代码中,您将循环完成每个位置的赋值,以填充从stdin中获得的使用“scanf()”的字符,这很好,现在,它在循环4次之后看起来是这样的:

|1|2|3|4|§|  

Note, there is not a terminating NULL (0) in the last position.
By using memset(array, 0, 5); the created buffer would look like this:

注意,在最后一个位置没有终止NULL(0)。使用memset(数组,0,5);创建的缓冲区如下所示:

|0|0|0|0|0|  

And the resulting populated buffer like this:

得到的填充缓冲区如下所示:

|1|2|3|4|0|  //properly terminated char buf is required for a C string

#2


2  

The countdown array isn't NULL terminated so printf doesn't know where to stop.

倒计时数组不是空的,所以printf不知道在哪里停止。

You'll want to allocate count + 1 characters and then set the last character to NULL.

您需要分配count + 1字符,然后将最后一个字符设置为NULL。

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

int main()
{
    char array[100];

    printf("Shoot me consecutive numbers, end with 0\n");
    scanf("%s",&array);
    int count = strlen(array);
    char countdown[count + 1];
    int reverseIndex;
    int index = 0;
    for(reverseIndex = count-1;reverseIndex >= 0;reverseIndex--)
    {
        char possibleNumber = array[reverseIndex];
        if(isdigit(possibleNumber) && possibleNumber != '0')
        {
            countdown[index] = possibleNumber;
            index++;
        }
    }
    countdown[index] = 0;
    printf("countdown : %s\n",countdown);
    return 0;
}

#1


2  

One immediate error is this line:

一个直接的错误是:

you need to provide enough room for the NULL terminator in this line:

您需要为这一行的空终止符提供足够的空间:

char countdown[count + 1];//added +1  

Another is:

另一个原因是:

scanf("%s",&array);  

Change it to:

把它改成:

scanf("%s",array); //%s expects char *, &array is of type char (*)[100], parameter type mismatch 

I made these edits to the original code (see in-line comments), also used call to memset() to initialize countdown, and it runs: (results shown below)

我对原始代码进行了这些编辑(请参阅内联注释),还使用对memset()的调用来初始化倒计时,它运行:(结果如下所示)

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

int main()
{
    char array[100];

    printf("Shoot me consecutive numbers, end with 0\n");
    scanf("%s",array);//removed &
    int count = strlen(array);
    char countdown[count+1];//add room for NULL terminator
    int reverseIndex;
    int index = 0;
    memset(countdown, 0, count+1);//added to initialize all elements of char array to NULL
    for(reverseIndex = count-1;reverseIndex >= 0;reverseIndex--)
    {
        char possibleNumber = array[reverseIndex];
        if(isdigit(possibleNumber) && possibleNumber != '0')
        {
            countdown[index] = possibleNumber;
            index++;
        }
    }
    printf("countdown : %s\n",countdown);

    getchar();
    getchar();
    return 0;
}

Input and output:

输入和输出:

奇怪的字符输出在倒计时算法与超过4字符输入

EDIT to answer comment question about undesired characters in result
(and original question: ...But if I input 12340, I end up having 4321(↨@... )

编辑以回答关于结果中不希望出现的字符的评论问题(以及原始问题:……)但是如果我输入12340,我有4321(↨@……)

When char countdown[count+1]; is created, there is no guarantee of the contents.
That is, each position can be filled with any random set of bits.
Say array is defined as char array[5]; If not initialized, it may look like this in memory:

当char倒计时(数+ 1);是创建的,没有内容的保证。也就是说,每个位置都可以包含任意一组比特。设数组定义为char数组[5];如果没有初始化,在内存中可能是这样的:

|€|Œ|™|¢|§|  

Later in your code, you loop through to make assignments to each position to
populate with characters obtained using `scanf() from stdin, which is fine,
Now, it looks like this after looping 4 times:

在您的代码中,您将循环完成每个位置的赋值,以填充从stdin中获得的使用“scanf()”的字符,这很好,现在,它在循环4次之后看起来是这样的:

|1|2|3|4|§|  

Note, there is not a terminating NULL (0) in the last position.
By using memset(array, 0, 5); the created buffer would look like this:

注意,在最后一个位置没有终止NULL(0)。使用memset(数组,0,5);创建的缓冲区如下所示:

|0|0|0|0|0|  

And the resulting populated buffer like this:

得到的填充缓冲区如下所示:

|1|2|3|4|0|  //properly terminated char buf is required for a C string

#2


2  

The countdown array isn't NULL terminated so printf doesn't know where to stop.

倒计时数组不是空的,所以printf不知道在哪里停止。

You'll want to allocate count + 1 characters and then set the last character to NULL.

您需要分配count + 1字符,然后将最后一个字符设置为NULL。

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

int main()
{
    char array[100];

    printf("Shoot me consecutive numbers, end with 0\n");
    scanf("%s",&array);
    int count = strlen(array);
    char countdown[count + 1];
    int reverseIndex;
    int index = 0;
    for(reverseIndex = count-1;reverseIndex >= 0;reverseIndex--)
    {
        char possibleNumber = array[reverseIndex];
        if(isdigit(possibleNumber) && possibleNumber != '0')
        {
            countdown[index] = possibleNumber;
            index++;
        }
    }
    countdown[index] = 0;
    printf("countdown : %s\n",countdown);
    return 0;
}