Printf打印的字符多于我的字符串中包含的字符

时间:2018-01-20 01:39:21

标签: c pointers printf

我必须编写一个像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;
}      

1 个答案:

答案 0 :(得分:1)

chptr = (char *)malloc(i-j+1); //giving +1 for the \0 at the end

您为终止\0正确分配了内存,但实际上在哪里添加&#34; \ 0到最后&#34;?

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

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

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

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

具有更高的效率。而且,再次,不要忘记将目标缓冲区置零。

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

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

将在目标中生成一个正确的以零结尾的字符串。 (虽然你不会经常看到sprintf以这种方式使用过。)