在c中反转数组 - 不会打印 -

pew*_*pew 6 c arrays printf reverse fgets

此代码的问题在于,在用户在命令行中输入某些文本后,它实际上不会打印任何内容.

代码的目的是接受用户在文件名后通过命令提示符输入的行数.然后用户将输入内容进行反转.该程序应该反转每行的用户输入.

示例输入=大红狗

示例输出=狗红大

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define SIZE 80

char * reverseWords(char *string);

//argc is the count of cmd arguments.
//each command line argument is of type string
int main(int argc, char *argv[]){

    //initialize local variables
    int i;
    int N;
    char str[SIZE];

    for(i = 1; i <argc; i++)
    {
        //set N equal to the users number in the command line 
        N = atoi(argv[i]);
    }

    if(argc != 2){//2 means that something is in the argument.
        printf("ERROR: Please provide an integer greater than or equal to 0");
        exit(1);//exit the program
    }else if(N < 0){//We cant have a negative array size.
        printf("ERROR: Please provide an integer greater than or equal to 0");
        exit(1);//exit the program
    }else{
        for(i = 0; i < N; i++){
            /*
            fgets(pointer to array, max # of chars copied,stdin = input from keyboard) 
            */
            fgets(str,SIZE,stdin);

            printf("%s", reverseWords(str)); //<---does not print anything....
        }           
    }
    return 0;
}   


char * reverseWords(char *line){

    //declare local strings 
    char *temp, *word;
    //instantiate index
    int index = 0;
    int word_len = 0;
    /*set index = to size of user input
        do this by checking if the index of line is
        equal to the null-character.
    */
    for(int i = 0; line[i] != '\0';i++)
    {
        index = i;//index = string length of line.
    }

    //check if index is less than 0.
    //if not we decrement the index value.

    for(index; index != -1; index--){
        //checking for individual words or letters
        if(line[index] == ' ' && word_len > 0){
            strncpy(word,line,word_len);
            strcat(temp , (word + ' '));
            word_len = 0;

        }else if(isalnum(line[index])){
            word_len == word_len+1;
        }//end if

    }//end loop

    //copy over the last word after the loop(if any)
    if(word_len > 0){
        strncpy(word,line,word_len);
        strcat(temp,word);
    }//end if
    line = temp;
    return line;
}//end procedure 
Run Code Online (Sandbox Code Playgroud)

Dav*_*ica 6

毫无疑问,reverseWords什么都不打印.为什么?

char * reverseWords(char *line){
    ...
    char *temp, *word;
    ...
    line = temp;
    return line;
} //end procedure
Run Code Online (Sandbox Code Playgroud)

line指向哪里?(至temp).temp宣布在哪里?(in reverseWords).分配了多少存储空间temp(无 - 它是未初始化的指针)

此外,reverseWords当函数返回时,与函数关联的内存会发生什么?(它被破坏了......),所以即使你做过类似的事情char temp[strlen(line)+1] = "";,reverseWords也会冒险进入Undefined Behavior,因为你返回的指针,指向返回reverseWords时被破坏的堆栈框架内的某处reverseWords...

你是如何解决这个问题的?您有三个选项,(1)将第二个指针传递给具有足够存储空间的第二个数组,例如:

char *revwords (char *rline, char *line)
Run Code Online (Sandbox Code Playgroud)

或者,(2)动态分配存储,temp以便与之相关的存储器能够temp存活reverseWords,或者

(3)使用一个足够大阵列tempreverseWords并覆盖line在与所述数据temp的返回之前.(例如使用strcpy而不是分配line = temp;)

虽然动态分配是直接的,并且创建一个单独的数组reverseWords很好,但您可能最好将第二个足够大小的数组作为参数传递给reverseWords.

完全不清楚你在代码中使用argcargv参数做了什么,main从下面的例子中省略了参数.以下是反转读取的每一行中的单词的简短示例stdin,

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

#define SIZE 256

char *revwords (char *rline, char *line);

int main (void) {

    char line[SIZE] = "", rline[SIZE] = ""; /* storage for line/rline */

    while (fgets (line, SIZE, stdin)) { /* for each line on stdin */
        printf ("\n line: %s\nrline: %s\n", line, revwords (rline, line));
        *rline = 0; /* set first char in rline to nul-byte */
    }

    return 0;
}

char *revwords (char *rline, char *line)
{
    size_t lnlen = strlen (line);   /* length of line */
    /* pointer, end-pointer, rev-pointer and flag pointer-to-space */
    char *p = line + lnlen - 1, *ep = p, *rp = rline, *p2space = NULL;

    if (!line || !*line) {  /* validate line not NULL and not empty */
        fprintf (stderr, "revwords() error: 'line' empty of null.\n");
        return NULL;
    }

    if (*ep == '\n')    /* if line ends in '\n' -- remove it */
        *ep-- = 0;
    else                /* warn if no '\n' present in line */
        fprintf (stderr, "warning: no POSIX '\\n' found in line.\n");

    for (; ep >= line; ep--) {  /* for each char from end-to-beginning */
        if (*ep == ' ') {               /* is it a space? */
            size_t len = p - ep;        /* get the length of the word */
            strncat (rp, ep + 1, len);  /* concatenate word to rline  */
            if (p == line + lnlen - 1)  /* if first word, append ' '  */
                strcat (rp, " ");
            p = ep;                     /* update p to last ' '  */
            p2space = ep;               /* set flag to valid pointer */
        }
    }
    strncat (rp, line, p - line);       /* handle first/last word */

    if (!p2space) { /* validate line contained ' ', if not return NULL */
        fprintf (stderr, "revwords() error: nothing to reverse.\n");
        return NULL;
    }

    return rline;   /* return pointer to reversed line */
}
Run Code Online (Sandbox Code Playgroud)

注意:如果传入时没有'\n'存在,您可能会尝试读取比字符长的行(或者您正在读取文件末尾没有POSIX 的最后一行),并且您需要处理按要求.我在这里简单地警告一下.linerevwordsSIZE'\n'

示例使用/输出

$ printf "my dog has fleas\nmy cat does too\n" | ./bin/str_rev_words

 line: my dog has fleas
rline: fleas has dog my

 line: my cat does too
rline: too does cat my
Run Code Online (Sandbox Code Playgroud)

仔细看看,如果您有任何疑问,请告诉我.有几种方法可以解决这个问题,如果他们以合理有效的方式正确处理逆转,那么没有人比另一个更正确.随便挑选.

如果您喜欢使用字符串库函数而不是指针算法,则可以始终执行以下操作:

char *revwords (char *rline, char *line)
{
    /* length, pointer, end-pointer, pointer-to-space, copy of line */
    size_t len = strlen (line);
    char *p = NULL, *p2space = NULL, copy[len+1];

    if (!line || !*line) {  /* validate line not NULL and not empty */
        fprintf (stderr, "revwords() error: 'line' empty of null.\n");
        return NULL;
    }

    if (line[len-1] == '\n')    /* remove trailing newline */
        line[--len] = 0;
    else                /* warn if no '\n' present in line */
        fprintf (stderr, "warning: no POSIX '\\n' found in line.\n");

    strncpy (copy, line, len + 1);  /* copy line to 'copy' */

    /* for each ' ' from end-to-beginning */
    while ((p = strrchr (copy, ' '))) {
        strcat (rline, p + 1);          /* append word to rline */
        strcat (rline, " ");            /* followed by a space  */
        p2space = p;                    /* set p2space to p     */
        *p2space = 0;                   /* nul-terminate copy at p */
    }

    if (p2space) {              /* validate space found in line */
        *p2space = 0;           /* nul-terminate at space       */
        strcat (rline, copy);   /* concatenate first/last word  */
    }
    else {                      /* no ' ' in line, return NULL  */
        fprintf (stderr, "revwords() error: nothing to reverse.\n");
        return NULL;
    }

    return rline;   /* return pointer to reversed line */
}
Run Code Online (Sandbox Code Playgroud)

注意:虽然不是错误,但C的标准编码样式避免使用caMelCaseMixedCase变量或函数名称支持所有小写,同时保留用于宏和常量的大写名称.离开caMelCase或者MixedCase用于java或C++.(这是它的风格,所以这是你的选择,但它确实说明了第一印象时你的代码)