简体   繁体   English

如何将字符串返回到 function 中的指针字符串参数?

[英]How do I return the string to a pointer string argument in function?

I have trouble trying to return the string that is scanned in a function and return the string to the first pointer string argument.我无法尝试返回在 function 中扫描的字符串并将该字符串返回到第一个指针字符串参数。

The string is a new thing I just learn this week.字符串是我这周刚学的新东西。 I tested passing back arguments as integer and character, and both of them work.我测试了将 arguments 作为 integer 和字符传回,它们都有效。 The code is as follows.代码如下。 This is just part of the code because the whole project is in 3 files.这只是代码的一部分,因为整个项目在 3 个文件中。 As the code shows, the string is meant to send as an address (the string does not need a & sign).如代码所示,该字符串旨在作为地址发送(该字符串不需要 & 符号)。 The function scans the input string, and the string gets sent back as an argument. function 扫描输入字符串,并将该字符串作为参数发回。

To be honest, this is my assignment, using return to send back the string is not an option.老实说,这是我的任务,使用 return 发回字符串不是一个选项。

` `

char stringValue[7] = { '\0' };
input(stringValue, 4, 6);
printf("The string is %s", stringValue);

void input(char* string, int minimum, int maximum)
{
    char inputs[7];

    scanf("%[^\n]", inputs);

    *string = charInRange;
}

` `

When I run it, the printing of the value is random.当我运行它时,值的打印是随机的。 I tested with other tool, and it said:我用其他工具测试过,它说:

"assignment makes from pointer without a cast." “赋值是从指针进行的,没有强制转换。”

I am sure that the problem is probably the line assigned input to the pointer.我确信问题可能出在将输入分配给指针的行。 I think it's some format error.我认为这是一些格式错误。 I tried adding some &, *, or removing them.我尝试添加一些 &、* 或删除它们。 I spent the whole testing and searching for an answer but no result.我花了整个测试和寻找答案但没有结果。

Continuing from my comments, your primary problem in input() is you read into the array char inputs[7];继续我的评论,您在input()中的主要问题是您读入数组char inputs[7]; with scanf("%[^\n]", inputs);scanf("%[^\n]", inputs); and then attempt to assign charInRange (nowhere declared in your code) as the first character in string .然后尝试将charInRange (在您的代码中未声明)分配为string中的第一个字符。 This won't compile.这不会编译。

When you attempt to print stringvalue back in main, since charInRange isn't defined (or isn't initialized or is initialized outsize the range for ASCII characters), you get gibberish.当您尝试在 main 中打印回stringvalue时,由于charInRange未定义(或未初始化或初始化超出 ASCII 字符的范围),您会得到乱码。

As explained in the comments, the input[] array isn't necessary.正如评论中所解释的, input[]数组不是必需的。 You have already declared storage for stringvalue in main() and are passing the address for that storage (the pointer char *string) to the input() function. You simply need to read into string in the input() function. The input[] array is unnecessary.您已经在main()中声明了字符串值的存储,并将该存储的地址(指针char *string)传递给input() stringvalue您只需要在input() function 中读入stringinput[]数组是不必要的。

However, before looking at how you can do that, when you are providing a buffer (a character array) for user-input -- Don't Skimp on Buffer Size .但是,在查看如何执行此操作之前,当您为用户输入提供缓冲区(字符数组)时——不要吝啬缓冲区大小 When you use scanf() with "%[ ]" the user can enter any number of characters beyond you array size, writing beyond the end of your array.当您将scanf()"%[ ]"一起使用时,用户可以输入超出数组大小的任意数量的字符,从而超出数组的末尾。 This is a favorite exploit by buffer overrun.这是缓冲区溢出最喜欢的漏洞利用。

If using the "%s" or "%[ ]" format specifiers with scanf() you must provide a field-width modifier to limit the number of characters that can be read.如果将"%s""%[ ]"格式说明符与scanf()一起使用,则必须提供字段宽度修饰符以限制可读取的字符数。 Failure to do so renders scanf() no safer than gets() .如果不这样做, scanf()就不会比gets()更安全。 See Why gets() is so dangerous it should never be used!请参阅为什么 gets() 如此危险,永远不应该使用它!

This is just one of the scanf() pitfalls, and one of the reasons why new C programmers are encouraged to take all user-input with fgets() .这只是scanf()陷阱之一,也是鼓励新 C 程序员使用fgets()获取所有用户输入的原因之一。

With that said, let's look at how we can write your input() function to only accept a user-input of between min and max chars.话虽如此,让我们看看我们如何编写您的input() function 以仅接受minmax字符之间的用户输入。 As mentioned, whenever you have conditions your input must meet, the approach is the loop continually reading input from the user (your read-loop ).如前所述,只要您有输入必须满足的条件,方法就是循环不断地从用户那里读取输入(您的read-loop )。 Check the length of what the user entered and only if the length is from min to max , break your read-loop and return.检查用户输入的内容的长度,只有当长度从minmax时, break你的读取循环并返回。

To ensure your read-buffer is sufficiently sized, make it larger than what you anticipate the max string you will accept is.为确保您的读取缓冲区大小足够,请使其大于您预期的最大字符串大小。 (a lot longer, you have a 4M stack on Linux and a 1M stack on Windows) a 1K buffer is fine. (更长的时间,Linux 上有 4M 堆栈,Windows 上有 1M 堆栈)1K 缓冲区就可以了。 On embedded systems where memory is limited, then adjust the buffer size down.在 memory 受限的嵌入式系统上,然后向下调整缓冲区大小。 When you need to set constants in your code #define them, don't just throw Magic Numbers like 4 and 6 in as parameters.当你需要在你的代码中设置常量时#define them,不要只把像46这样的幻数作为参数。 You can do that with:你可以这样做:

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

#define INPUTSZ 1024      /* if you need a constant, #define one (or more) */
#define MAXC 6
#define MINC 4

Now you can write your input() function similar to:现在你可以写你的input() function 类似于:

void input (char *string, size_t min, size_t max)
{
  /* loop continually until valid input given */
  for (;;) {
    size_t len;   /* length to test against min */
    
    fputs ("\nenter string: ", stdout); /* always prompt for input */
    
    /* take all user-input with fgets (into a larger buffer - don't skimp)
     * validate the return of every input function used.
     */
    if (!fgets (string, INPUTSZ, stdin)) {
      puts ("(user canceled input)");   /* return is NULL, Ctrl+d (z) used */
      *string = 0;                      /* set string as empty-string */
      return;
    }
    
    len = strcspn (string, "\n");       /* get length of input minus '\n' */
    string[len] = 0;                    /* overwrite '\n' with '\0' */
    
    if (min <= len && len <= max) {     /* condition met, break read loop */
      break;
    }
    
    /* handle invalid input */
    fprintf (stderr, "input must be %zu-%zu characters\n", min, max);
  }
}

( note: you can save the length while trimming the '\n' from string in a single step, eg string[(len = strcspn (string, "\n"))] = 0; , but that was split for readability above. Also note 0 and '\0' are equivalent. 0 being the ASCII value for the nul-character, see ASCII Table ) 注意:您可以在单个步骤中从string中修剪'\n'的同时保存长度,例如string[(len = strcspn (string, "\n"))] = 0; ,但为了上面的可读性,它被拆分了。还要注意0'\0'是等效的0是空字符的 ASCII 值,请参阅ASCII 表

And finally your main() , eg最后是你的main() ,例如

int main (void) {
  
  char stringvalue[INPUTSZ] = "";
  
  input (stringvalue, MINC, MAXC);
  
  if (*stringvalue) {
    puts (stringvalue);
  }
}

( note: the stringvalue is only printed if the user didn't cancel by generating a manual EOF with Ctrl + d ( Ctrl + z on windows)) 注意:仅当用户未通过使用Ctrl + d (Windows 上的Ctrl + z )生成手动EOF来取消时,才会打印stringvalue值)

Can you look and determine what line in the input() function allows you to make the test if (*stringvalue) ?您能否查看并确定input() function 中的哪一行允许您进行测试if (*stringvalue) Note *stringvalue is the same as *(stringvalue + 0) which is the pointer notation for stringvalue[0] .注意*stringvalue*(stringvalue + 0)相同,后者是stringvalue[0]的指针表示法。

Example Use/Output示例使用/输出

Does the code limit input to the proper number of characters?代码是否将输入限制为适当的字符数?

$ ./bin/inputmaxmin

enter string: 12
input must be 4-6 characters

enter string: 123
input must be 4-6 characters

enter string: 1234567
input must be 4-6 characters

enter string: 1234
1234

What about handling the user canceling input with Ctrl + d ?如何处理用户使用Ctrl + d取消输入?

$ ./bin/inputmaxmin

enter string: one hundred twenty-three
input must be 4-6 characters

enter string: (user canceled input)

Also, you seem a little iffy on pointers.另外,您似乎对指针有点怀疑。 Here are a couple of links that provide basic discussions of pointers that may help.这里有几个链接提供了可能有帮助的指针的基本讨论。 Difference between char pp and (char ) p? char pp 和 (char ) p 之间的区别? and Pointer to pointer of structs indexing out of bounds(?)... (ignore the titles, the answers discuss pointer basics)指向超出范围的结构指针的指针(?)... (忽略标题,答案讨论指针基础知识)

Look things over and let me know if you have questions.检查一下,如果您有任何问题,请告诉我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM