简体   繁体   English

读取用户输入并检查字符串

[英]Reading user input and checking the string

How does one check the read in string for a substring in C? 如何检查C的子字符串的读入字符串?

If I have the following 如果我有以下内容

char name[21];
fgets(name, 21, stdin);

How do I check the string for a series of substrings? 如何检查字符串中的一系列子字符串?

How does one check for a substring before a character? 如何检查字符前的子字符串? For example, how would one check for a substring before an = sign? 例如,如何检查=之前的子字符串?

Be wary of strtok() ; 警惕strtok() ; it is not re-entrant. 它不是可重入的。 Amongst other things, it means that if you need to call it in one function, and then call another function, and if that other function also uses strtok() , your first function is messed up. 除其他外,这意味着如果您需要在一个函数中调用它,然后再调用另一个函数,并且如果该另一个函数也使用strtok() ,则您的第一个函数就搞砸了。 It also writes NUL ( '\\0' ) bytes over the separators, so it modifies the input string as it goes. 它还在分隔符上写入NUL( '\\0' )字节,因此它会随即修改输入字符串。 If you are looking for more than one terminator character, you can't tell which one was found. 如果要查找多个终止符,则无法确定找到了哪个终止符。 Further, if you write a library function for others to use, yet your function uses strtok() , you must document the fact so that callers of your function are not bemused by the failures of their own code that uses strtok() after calling your function. 此外,如果您编写了供其他人使用的库函数,但您的函数使用strtok() ,则必须记录这一事实,以使函数调用者不会因调用strtok()后使用strtok()的自身代码失败而感到困惑。功能。 In other words, it is poisonous; 换句话说,它是有毒的。 if your function calls strtok() , it makes your function unreusable, in general; 如果您的函数调用strtok() ,通常会使您的函数不可重用; similarly, your code that uses strtok() cannot call other people's functions that also use it. 同样,使用strtok()代码无法调用也使用它的其他人的函数。

If you still like the idea of the functionality - some people do (but I almost invariably avoid it) - then look for strtok_r() on your system. 如果您仍然喜欢此功能的想法-有些人喜欢(但我几乎总是避免使用它)-然后在系统上寻找strtok_r() It is re-entrant; 它是可重入的; it takes an extra parameter which means that other functions can use strtok_r() (or strtok() ) without affecting your function. 它需要一个额外的参数,这意味着其他函数可以使用strtok_r() (或strtok() )而不会影响您的函数。

There are a variety of alternatives that might be appropriate. 有多种可能合适的替代方法。 The obvious ones to consider are strchr() , strrchr() , strpbrk() , strspn() , strcspn() : none of these modify the strings they analyze. 最明显的要考虑的是strchr() strrchr() strpbrk() strspn() strcspn()没有这些修改,他们分析的字符串。 All are part of Standard C (as is strtok() ), so they are essentially available everywhere. 所有这些都是标准C的一部分(与strtok() ),因此它们基本上在任何地方都可以使用。 Looking for the material before a single character suggests that you should use strchr() . 在单个字符之前查找材料建议您使用strchr()

Use strtok() to split the string into tokens. 使用strtok()将字符串拆分为令牌。

char *pch;
pch = strtok (name,"=");
if (pch != NULL)
{
  printf ("Substring: %s\n",pch);
}

You can keep calling strtok() to find more strings after the = . 您可以继续在=之后调用strtok()以查找更多字符串。

You can use strtok but it's not reentrant and it destroys the original string. 您可以使用strtok但不能重入,它会破坏原始字符串。 Other (perhaps safer) functions to look into would be strchr , strstr , strspn , and perhaps the mem* variations. 其他(也许更安全)的功能可能是strchrstrstrstrspn ,也许还有mem*变体。 In general, I avoid strn* variants because, while they do "boinds checking," they still rely on the nul terminator. 通常,我避免使用strn*变体,因为尽管它们进行“绑定检查”,但它们仍然依赖于nul终止符。 They can fail on a valid string that just happens to be longer than you expected to deal with, and they won't actually prevent a buffer overrun unless you know the buffer size. 它们可能会因恰好比您预期要处理的更长的有效字符串而失败,并且除非您知道缓冲区大小,否则它们实际上不会阻止缓冲区溢出。 Better (IMHO) to ignore the terminator and know exactly how much data you're working with every time the way the mem* functions work. 更好(IMHO)忽略终止符,并确切地知道每次mem*函数工作时您正在处理多少数据。

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

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