C语言 使用 scanf 读取字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5406935/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reading a string with scanf
提问by abeln
I'm a little bit confused about something. I was under the impression that the correct way of reading a C string with scanf()went along the lines of
我对某事有点困惑。我的印象是,阅读 C 字符串的正确方法scanf()是
(never mind the possible buffer overflow, it's just a simple example)
(别介意可能的缓冲区溢出,这只是一个简单的例子)
char string[256];
scanf( "%s" , string );
However, the following seems to work too,
但是,以下似乎也有效,
scanf( "%s" , &string );
Is this just my compiler (gcc), pure luck, or something else?
这只是我的编译器(gcc),纯粹的运气,还是其他什么?
采纳答案by Gareth McCaughan
An array "decays" into a pointer to its first element, so scanf("%s", string)is equivalent to scanf("%s", &string[0]). On the other hand, scanf("%s", &string)passes a pointer-to-char[256], but it points to the same place.
数组“衰减”为指向其第一个元素的指针,因此scanf("%s", string)等效于scanf("%s", &string[0])。另一方面,scanf("%s", &string)传递一个指向-的指针char[256],但它指向同一个地方。
Then scanf, when processing the tail of its argument list, will try to pull out a char *. That's the Right Thing when you've passed in stringor &string[0], but when you've passed in &stringyou're depending on something that the language standard doesn't guarantee, namely that the pointers &stringand &string[0]-- pointers to objects of different types and sizes that start at the same place -- are represented the same way.
然后scanf,在处理其参数列表的尾部时,将尝试拉出一个char *. 当你传入stringor 时&string[0],这是正确的事情,但是当你传入时,&string你依赖于语言标准不能保证的东西,即指针&string和&string[0]-- 指向不同类型和大小的对象的指针从同一个地方开始——以同样的方式表示。
I don't believe I've ever encountered a system on which that doesn't work, and in practice you're probably safe. None the less, it's wrong, and it could fail on some platforms. (Hypothetical example: a "debugging" implementation that includes type information with every pointer. I thinkthe C implementation on the Symbolics "Lisp Machines" did something like this.)
我不相信我曾经遇到过无法运行的系统,实际上您可能是安全的。尽管如此,这是错误的,并且在某些平台上可能会失败。(假设示例:包含每个指针的类型信息的“调试”实现。我认为Symbolics“Lisp Machines”上的 C 实现做了类似的事情。)
回答by angelita
I think that this below is accurate and it may help. Feel free to correct it if you find any errors. I'm new at C.
我认为以下内容是准确的,可能会有所帮助。如果您发现任何错误,请随时更正。我是 C 的新手。
char str[]
- array of values of type char, with its own address in memory
- array of values of type char, with its own address in memory as many consecutive addresses as elements in the array
including termination null character
'\0'&str,&str[0]andstr, all three represent the same location in memory which is address of the first element of the arraystrchar *strPtr = &str[0]; //declaration and initialization
- char 类型的值数组,在内存中具有自己的地址
- char 类型值的数组,它在内存中的地址与数组中元素的连续地址一样多
包括终止空字符
'\0'&str,&str[0]并且str,所有三个代表存储器中的相同位置这是所述阵列的所述第一元件的地址str字符 *strPtr = &str[0]; //声明和初始化
alternatively, you can split this in two:
或者,您可以将其分为两部分:
char *strPtr; strPtr = &str[0];
strPtris a pointer to acharstrPtrpoints at arraystrstrPtris a variable with its own address in memorystrPtris a variable that stores value of address&str[0]strPtrown address in memory is different from the memory address that it stores (address of array in memory a.k.a &str[0])&strPtrrepresents the address of strPtr itself
strPtr是一个指向a的指针charstrPtr指向数组strstrPtr是一个变量,在内存中有自己的地址strPtr是一个存储地址值的变量&str[0]strPtr自己在内存中的地址与它存储的内存地址不同(内存中数组的地址又名 &str[0])&strPtr代表strPtr本身的地址
I think that you could declare a pointer to a pointer as:
我认为您可以将指向指针的指针声明为:
char **vPtr = &strPtr;
declares and initializes with address of strPtr pointer
用 strPtr 指针的地址声明和初始化
Alternatively you could split in two:
或者,您可以分为两部分:
char **vPtr;
*vPtr = &strPtr
*vPtrpoints at strPtr pointer*vPtris a variable with its own address in memory*vPtris a variable that stores value of address &strPtr- final comment: you can not do
str++,straddress is aconst, but you can dostrPtr++
*vPtr指向 strPtr 指针*vPtr是一个变量,在内存中有自己的地址*vPtr是一个存储地址值的变量 &strPtr- 最后评论:你不能做
str++,str地址是一个const,但你可以做strPtr++

