strlen 默认为“40”?
strlen defaulting to '40'?
新程序员从基础开始。
我需要编写一个代码来检查字符串(行)的长度并对其进行处理。在开始下一部分任务之前,我正在努力使长度正确。
当我 运行 下面的代码是 strlen(string1) 时发生了什么,无论我输入什么,它似乎都默认为“40”?
我不确定出了什么问题!
任何帮助将不胜感激。
#include <iostream>
#include <string.h>
#include <string>
using namespace std;
char line, just, jline;
void prompt();
int main() {
cout << "Enter a line of text: " << endl;
char string1[line];
cin >> line;
char string2[] = "1234567890123456789012345678901234567890";
line = strlen(string1);
just = strlen(string2);
cout << "Length of string is: " << strlen(string1) << endl;
if ((strlen(string1)) > (strlen(string2))) {
cout << "Error, your line must be less than 40 characters" << endl;
}
}
您的代码存在 2 个问题,如下所述:
问题 1
在标准 C++ 中,数组的大小必须是编译时间常数。这意味着您的程序中的以下内容不正确:
char string1[line]; //not standard C++ because line is not a constant expression
问题 2
请注意,这还有另一个问题。由于 line
是一个全局变量,它将被静态初始化为 0
。因此 char string1[line];
实际上等同于 char string1[0];
.
`但是来自 array declarators documentation:
If the expression is a constant expression, it shall have a value greater than zero.
因此,char string1[line];
也因此无效。
解决方案
更好的做法是 std::string
,如下所示:
#include <iostream>
#include <string>
int main() {
std::cout << "Enter a line of text: " << std::endl;
std::string inputLine;
std::getline(std::cin, inputLine);//take input from user and put it into inputLine
std::string var = "1234567890123456789012345678901234567890";
//----------------------------------------------------vvvvv----------->use size member function of std::string
std::cout << "Length of string is: " << inputLine.size() << std::endl;
if (inputLine.size() > var.size()) {
std::cout << "Error, your line must be less than 40 characters" << std::endl;
}
else
{
std::cout<<"valid input"<<std::endl;
}
}
Demo.
在上面的代码片段中,我们使用 std::string::size
知道 std::string
的 size/length。
此外,应尽可能避免使用全局变量。参考Are global variables bad?.
截至目前,您的 line 变量是 char 类型。这意味着它包含一个字符。如果要存储字符串,可以使用固定大小的字符数组(c-style 字符串)或字符串对象。在 C++ 中,字符串对象应该是首选,因为它们提供了比 c-style 字符串更广泛的优势,包括更高的安全性和更好的易用性。
如果你想获取用户输入的字符串对象的长度,你可以这样写
#include <iostream>
#include <string>
// if you don’t want to use std:: put using namespace std; after the includes
int main(){
std::string str;
int strLength
std::cout << “Enter a Single Word: “;
std::cin >> str;
strLength = str.lenght();
std::cout << “The length of the word is “ << strLength << std::endl;
return 0;
}
如果您想获得整行文本,您可以替换
std::cout << “Enter a Single Word: “;
std::cin >> str;
有
std::cout << “Enter a Line of text: “;
std::getline(cin, str);
您也可以使用 c-style 字符串和 strlen() 但是,安全地执行此操作要困难得多,并且通过编写比使用的固定大小数组的大小可能会导致问题,因为额外的数据可以写入不应该写入的区域,所以如果你刚开始,你应该使用字符串对象。
如果您想了解有关 std::string 的更多信息,请访问
https://en.cppreference.com/w/cpp/string/basic_string
关于 strlen 返回 40 的原因。strlen() 的工作方式是它采用一个称为指针的变量,该变量指向字符数组的开头,并遍历从指针开始的字符数组并查找一个称为空字符 '\0' 的特殊字符和 returns 数组中此空字符之前的字符数。如果 c-style 字符串不以空字符结尾,这可能会导致问题。
对于您提供的代码,string2 包含“”内的所有 40 个字符加上末尾的空字符,因此当使用 string2 调用 strlen() 时,它会计算空字符之前的 40 个字符字符.
在 string1 的情况下,当它被创建时,它的大小等于未初始化变量行中包含的值,在本例中显示为 0。这导致 string1 被创建为大小为 0(根据语言标准,这是未定义的行为,但在某些情况下它可能仍然“有效”)。因为 string2 后来在内存中直接在 string1 之后的位置创建,当 string1 被传递到 strlen 时创建的指向 string1 开头的指针指向 string2 的开头,导致 strlen 在调用 string1 时有效地测量 string2 的长度。
最后,作为一个提示。尽量避免将变量放在全局范围内(在函数或其他封装实体之外,如 类)。这些全局变量有被函数以可能导致代码问题的方式无意更改的风险。通常最好将这些变量放在 main 中并将它们传递给您要在其中使用它们的函数。如果您想让函数影响这些变量,您可以将它们作为引用传递给函数。为此,您可以在变量将作为传入函数的参数类型后面放置一个 &,如下所示。
void function(std::string &str);
//… some other code
//… somewhere in main or another function
function(alteredString);
// some other code …
新程序员从基础开始。 我需要编写一个代码来检查字符串(行)的长度并对其进行处理。在开始下一部分任务之前,我正在努力使长度正确。
当我 运行 下面的代码是 strlen(string1) 时发生了什么,无论我输入什么,它似乎都默认为“40”?
我不确定出了什么问题! 任何帮助将不胜感激。
#include <iostream>
#include <string.h>
#include <string>
using namespace std;
char line, just, jline;
void prompt();
int main() {
cout << "Enter a line of text: " << endl;
char string1[line];
cin >> line;
char string2[] = "1234567890123456789012345678901234567890";
line = strlen(string1);
just = strlen(string2);
cout << "Length of string is: " << strlen(string1) << endl;
if ((strlen(string1)) > (strlen(string2))) {
cout << "Error, your line must be less than 40 characters" << endl;
}
}
您的代码存在 2 个问题,如下所述:
问题 1
在标准 C++ 中,数组的大小必须是编译时间常数。这意味着您的程序中的以下内容不正确:
char string1[line]; //not standard C++ because line is not a constant expression
问题 2
请注意,这还有另一个问题。由于 line
是一个全局变量,它将被静态初始化为 0
。因此 char string1[line];
实际上等同于 char string1[0];
.
`但是来自 array declarators documentation:
If the expression is a constant expression, it shall have a value greater than zero.
因此,char string1[line];
也因此无效。
解决方案
更好的做法是 std::string
,如下所示:
#include <iostream>
#include <string>
int main() {
std::cout << "Enter a line of text: " << std::endl;
std::string inputLine;
std::getline(std::cin, inputLine);//take input from user and put it into inputLine
std::string var = "1234567890123456789012345678901234567890";
//----------------------------------------------------vvvvv----------->use size member function of std::string
std::cout << "Length of string is: " << inputLine.size() << std::endl;
if (inputLine.size() > var.size()) {
std::cout << "Error, your line must be less than 40 characters" << std::endl;
}
else
{
std::cout<<"valid input"<<std::endl;
}
}
Demo.
在上面的代码片段中,我们使用 std::string::size
知道 std::string
的 size/length。
此外,应尽可能避免使用全局变量。参考Are global variables bad?.
截至目前,您的 line 变量是 char 类型。这意味着它包含一个字符。如果要存储字符串,可以使用固定大小的字符数组(c-style 字符串)或字符串对象。在 C++ 中,字符串对象应该是首选,因为它们提供了比 c-style 字符串更广泛的优势,包括更高的安全性和更好的易用性。
如果你想获取用户输入的字符串对象的长度,你可以这样写
#include <iostream>
#include <string>
// if you don’t want to use std:: put using namespace std; after the includes
int main(){
std::string str;
int strLength
std::cout << “Enter a Single Word: “;
std::cin >> str;
strLength = str.lenght();
std::cout << “The length of the word is “ << strLength << std::endl;
return 0;
}
如果您想获得整行文本,您可以替换
std::cout << “Enter a Single Word: “;
std::cin >> str;
有
std::cout << “Enter a Line of text: “;
std::getline(cin, str);
您也可以使用 c-style 字符串和 strlen() 但是,安全地执行此操作要困难得多,并且通过编写比使用的固定大小数组的大小可能会导致问题,因为额外的数据可以写入不应该写入的区域,所以如果你刚开始,你应该使用字符串对象。
如果您想了解有关 std::string 的更多信息,请访问 https://en.cppreference.com/w/cpp/string/basic_string
关于 strlen 返回 40 的原因。strlen() 的工作方式是它采用一个称为指针的变量,该变量指向字符数组的开头,并遍历从指针开始的字符数组并查找一个称为空字符 '\0' 的特殊字符和 returns 数组中此空字符之前的字符数。如果 c-style 字符串不以空字符结尾,这可能会导致问题。
对于您提供的代码,string2 包含“”内的所有 40 个字符加上末尾的空字符,因此当使用 string2 调用 strlen() 时,它会计算空字符之前的 40 个字符字符.
在 string1 的情况下,当它被创建时,它的大小等于未初始化变量行中包含的值,在本例中显示为 0。这导致 string1 被创建为大小为 0(根据语言标准,这是未定义的行为,但在某些情况下它可能仍然“有效”)。因为 string2 后来在内存中直接在 string1 之后的位置创建,当 string1 被传递到 strlen 时创建的指向 string1 开头的指针指向 string2 的开头,导致 strlen 在调用 string1 时有效地测量 string2 的长度。
最后,作为一个提示。尽量避免将变量放在全局范围内(在函数或其他封装实体之外,如 类)。这些全局变量有被函数以可能导致代码问题的方式无意更改的风险。通常最好将这些变量放在 main 中并将它们传递给您要在其中使用它们的函数。如果您想让函数影响这些变量,您可以将它们作为引用传递给函数。为此,您可以在变量将作为传入函数的参数类型后面放置一个 &,如下所示。
void function(std::string &str);
//… some other code
//… somewhere in main or another function
function(alteredString);
// some other code …