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)
毫无疑问,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)使用一个足够大阵列temp中reverseWords并覆盖line在与所述数据temp的返回之前.(例如使用strcpy而不是分配line = temp;)
虽然动态分配是直接的,并且创建一个单独的数组reverseWords很好,但您可能最好将第二个足够大小的数组作为参数传递给reverseWords.
完全不清楚你在代码中使用argc和argv参数做了什么,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的标准编码样式避免使用caMelCase或MixedCase变量或函数名称支持所有小写,同时保留用于宏和常量的大写名称.离开caMelCase或者MixedCase用于java或C++.(这是它的风格,所以这是你的选择,但它确实说明了第一印象时你的代码)