C++中输入字符数组的特定验证
Specific validation of input char array in C++
一段时间以来,我在正确验证字符数组时遇到了问题。我已经看到了许多很好的方法来做到这一点,但仍然没有弄清楚如何在我的代码中组合一些东西。 不知道如何正确解决这个简单的问题。
struct student{
char fullname[SLEN];
char hobby[SLEN];
int ooplevel;
};
int getinfo( student*, int );
void display1( student );
void display2( const student* );
void display3( const student pa[], int );
int main()
{
std::cout << "Group size: ";
int class_size;
std::cin >> class_size;
while( std::cin.get() != 'n' )
continue;
student* ptr_stu = new student[class_size];
int entered = getinfo( ptr_stu, class_size );
for( int i=0; i<entered; ++i )
{
display1( ptr_stu[i] );
display2( &ptr_stu[i] );
}
display3( ptr_stu, entered );
delete [] ptr_stu;
std::cout << "Gotowe.n";
getchar();
return 0;
}
int getinfo( student* stu, int n )
{
int i=0;
while( i<n ){
std::cout << "Fullname " << i+1 << ": ";
std::cin >> stu[i].fullname;
std::cout << "Hobby " << i+1 << ": ";
std::cin >> stu[i].hobby;
std::cout << "OOPlevel " << i+1 << ": ";
std::cin >> stu[i].ooplevel;
++i;
}
}
我只是确定必须有办法验证字符数组:
1.最大长度为 30
2。必须包含 2 个单词,因为它的第一个和第二个名称
3.不能包含数字
4。如果用户按 Enter 而不键入任何内容,则会导致中断循环
5.一切都在函数中,其中一个参数是指向将存储名称的结构的指针。
原谅我这个原始的问题。我知道我的代码中甚至没有尝试解决这个问题,但我只是不想把我创建的垃圾放在这里。
- 最大长度为 30
std::cin >> std::setw(30) >> ...;
- 必须包含 2 个单词,因为它的第一个和第二个名称
运气不好operator>>
,它会停在空白处。所以你要么需要读两次,要么读一整行(std::getline
(。
- 不能包含数字
好吧,遍历字符串并用isdigit
检查每个字符:
for(unsigned char c : theString)
{
if(isdigit(c))
// error!
}
- 如果用户按 Enter 键而不键入任何内容,则会导致中断循环
同样,operator>>
运气不好 - 它只会忽略空格,包括换行符......同样,您需要std::getline
:
std::string s;
std::getline(std::cin, s);
if(s.empty())
break; // or return
不过,不确定这是否是一个好主意,因为用户可能会意外地按回车键。那么用户只输入空白怎么办?行为非空,但仍然不包含任何信息...
- 一切都在函数中,其中一个参数是指向将存储名称的结构的指针。
不确定你的意思 - 你已经有了 getInfo,不是吗?
您可能会发现并非上述所有内容都能很好地组合,例如,获取空行仅适用于std::getline
,因此您将不得不一直使用它......
现在想知道 - 你使用C++ - 你为什么不使用C++标准容器?它们使您的生活更加轻松:
struct Student
{
std::string fullName; // I personally would prefere surname and forename anyway...
std::string hobby;
// ...
}
int getInfo(std::vector<Student>& students)
{
for(auto& student : students)
// ^ enforce reference to actually modify the objects in the vector
{
// read input...
}
// you should return something!!!
return students.size();
}
好的,对于过早退出循环,我们需要一个返回值 - 我们可以从向量提供的连续内存中获利,因此以下内容是有效的:
if(emptyLine)
return &student - students.data();
学生全名:
// we don't need any additional buffer, can read into target directly...
std::getline(std::cin, student.fullName);
auto i = student.fullName.begin(), j = i;
while(isspace((unsigned char)(*i))
++i;
while(!isspace((unsigned char)(*i))
{
if(isdigit((unsigned char)(*i))
// error handling!
*j++ = *i++;
}
*j++ = ' '; // separator
// now sure name analogously!
student.fullName.resize(j - student.fullName.begin());
您可能已经注意到:这会读取整个字符串并就地修改它。喜欢吗?
上面的代码中还有一些错误,你看到了吗?在分配分隔空格之前,必须在 while 循环中检查 i!= fullName.end()
,以确保不超过字符串的当前范围!我就交给你了...
您现在也应该为显示功能使用矢量:
void display(std::vector const& students);
// ^ no need for additional identifiers, C++ supports overloads
// ^ const vector, you won't modify it
// ^ reference to prevent a copy
循环提示:
for(auto& student : students)
使用 auto 关键字可以防止您关心对象是否是常量。然后,引用会阻止您复制数据,因此这是您应该首选的...
类似地,对于单个学生:
void display(Student const& student);
// ^ overload!
// ^ ^ const reference
主要:
//student* ptr_stu = new student[class_size];
//^ replaced by:
std::vector<Student> students(class_size);
// ^ or whatever name you like
// ^ one of vectors constructors accepts a size
// this is then equivalent to:
// std::vector<...> v; v.resize(n);
// ^ (empty vector)
// and no need for deletion either...
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组的地址分配给变量并删除
- 从C++本机插件更新Vector3数组
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 如何在C++中检查2D数组中负值的输入验证
- 在C++中使用字符数组进行输入验证
- C++中的字符数组验证
- 在C++中使用字符数组进行用户输入验证
- C++ 中字符数组的输入验证
- C++中输入字符数组的特定验证
- 队列验证层错误:队列族索引在 pCreateInfo->pQueueCreateInfos 数组中不是唯一的
- 如何使用数组字符串进行输入验证
- C++ 在将输入值添加到数组之前对其进行验证
- 在数组中输入5个元素,检查验证,然后输出C++
- 使用基于C++11范围的循环验证数组值?[无矢量]
- 验证内存设置为默认值后数组中的更改
- C++ 字符数组大小验证
- 在 C 中验证数组的大小
- 数组边界检查和输入验证
- 验证数组没有重复的值