【问题标题】:Printf prints more character than those contained in my string [closed]Printf 打印的字符比我的字符串中包含的字符多[关闭]
【发布时间】:2018-01-20 01:39:21
【问题描述】:

我必须编写一个像 shell 一样工作的程序。我编写了从用户那里获取输入的函数。我还编写了将其拆分为参数的函数。 我第一次输入的时候,效果很好,但是第二次,它会在我输入的字符之后打印不同的字符。我不必在程序中打印它。我只是为了看看它是否正常工作。我在网上阅读了一堆东西,但我无法弄清楚我的错误。我想它在 makeArgs() 中,但我无法确定它。

另外,当我给它一个输入时,readline 函数会在字符串的末尾添加一个 \n。我想这是因为我按下了回车键。我设法通过手动替换它来解决这个问题,但我想知道它是否正常。

非常感谢任何帮助。 谢谢你

Screenshot of Xterm after 2 inputs.

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

int getText();
int makeArgs();

char *textEntre;
size_t nbCharacters;
char **arguments;

int main (void)
{

    while (1){
        getText();
        int nbArguments = makeArgs();
        for(int i =0; i<5; i++){
            printf("%s \n",arguments[i]);
        }
        for(int i=0; i<nbArguments; i++){//free the char ptrs at the end
            free(arguments[i]);
        }
    }
    free(textEntre);
    free(arguments);
    return 0;
}

int getText(){
    size_t buffersize = 0;
    nbCharacters = getline(&textEntre, &buffersize, stdin);
    textEntre[nbCharacters-1] =' '; // when I press enter it regiter the enter as \n so I replace it with a space
    return 0;
}

int makeArgs(){
    arguments = (char **)malloc(sizeof(char*)*20);
    int i;
    int j = 0;
    int k = 0;
    int nbElem = 20; //the number of ptrs that can be in arguments
    for(i = 0; i<nbCharacters; i++){
       if(i == 20){ //increases the memory allocated if there are more than 20 arguments
            nbElem = nbElem *2;
            arguments = (char **)realloc(arguments, sizeof(char*)*nbElem);
       }
       if(textEntre[i] == '"'){ //checks for ""
            i++;
            while(textEntre[i] != '"'){
                i++;
            }
       }
       if(textEntre[i] == ' ' && textEntre[i-1] == ' '){ // eliminates useless spaces
            j++;
       }
       else if(textEntre[i] == ' '){ //save a single argument
           char * chptr;
           chptr = (char *)malloc(i-j+1); //giving +1 for the \0 at the end
           strncpy(chptr, &textEntre[j], i-j);
           arguments[k] = chptr;
           k++;
           j = i +1;
       }
    }
    return k;
}      

【问题讨论】:

    标签: c pointers printf


    【解决方案1】:
    chptr = (char *)malloc(i-j+1); //giving +1 for the \0 at the end
    

    您为终止 \0 正确分配了内存,但您实际上在哪里添加了“末尾的 \0”?

    strncpy(chptr, &textEntre[j], i-j);
    

    strncpy 不一定以零终止目标缓冲区。你必须自己做。

    事实上,在这个特定的应用程序中,strncpy 是一个相当不合适的函数:它不会给你任何超过普通的memcpy 的功能,并且可能效率较低。你可以这样做

    memcpy(chptr, &textEntre[j], i - j);
    

    可能会提高效率。同样,不要忘记对目标缓冲区进行零终止。

    或者您可以使用sprintf 用于以下相同目的

    sprintf(chptr, "%.*s", i - j, &textEntre[j]);
    

    这将在目标中生成正确的以零结尾的字符串。 (尽管您不会看到 sprintf 经常以这种方式使用。)

    【讨论】:

    • 解决了!!非常感谢!!我将其更改为 memcpy 并手动添加了 \0。
    • @ryyker:这就是我所说的“一般”。 strncpy 的初衷与以零结尾的字符串完全没有直接关系。
    猜你喜欢
    • 2018-05-06
    • 2020-06-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-03
    • 2018-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多