user-0 提问: 从常量字符数组中获取指定字符的索引，还有什么好办法，谢谢

回复:
user: user-1
content: 引用 19 楼 sys0613 的回复:[quote=引用 17 楼 zhao4zhong1 的回复:] [code=c]#pragma comment(lib,"user32") 这是啥。。。。[/quote] 告诉你啥叫“羞羞的铁拳”，哦不，“怪怪的字符”。

user: user-2
content: 引用 18 楼 sys0613 的回复:[quote=引用 15 楼 cfjtaishan 的回复:] [quote=引用 14 楼 sys0613 的回复:] [quote=引用 12 楼 cfjtaishan 的回复:] [quote=引用 8 楼 sys0613 的回复:] [quote=引用 5 楼 cfjtaishan 的回复:] [quote=引用 2 楼 sys0613 的回复:] [quote=引用 1 楼 jianwen0529 的回复:] 可以，不过查找不到返回NULL，此刻要进行判断并处理  自己可以写一份函数，也就两三句代码的事情，重点是可以控制。比如判断两个参数的有效性，直接返回索引等等 嗯，写函数防止找不到的NULL，还需要控制别的么？？我其实主要是担心两个指针地址相减会不会偶发一些不兼容的问题。产生不可控制的错误？谢谢[/quote] 应该不会，因为strchr返回也是指向传入参数的相对地址，不会有不兼容的问题。要么找到，返回传入参数的某个字符位置的地址，要么返回NULL，未找到。  不用strchr可能会更好，因为想要的是某个字符所在的位置，那么直接遍历比较即可。若找到返回对应的位置，否则返回-1；通过自定义函数来得到；  #include <stdio.h>   int get_pos(const char *str, int key);  int main(void) {     const char *str = "helloworld";      printf("Pos = %d\n", get_pos(str, 'w'));      return 0; }  int get_pos(const char *str, int key) {     int i;     for (i = 0; str[i]; i++)         if (key == str[i])             break;      if (!str[i])         return -1;      return i; } 参考一下吧[/quote]  好的，谢谢了，自己写这种遍历和strchr哪个效率更好呢？我本身就有数组的长度。。我直接循环遍历可能比你这个还省事。。。[/quote] 还有比这个效率高的。可以贴出来，一起研究下； [/quote] 我是说我事先知道数组长度。。。我担心你那个  if (!str[i])，最后一位可能不是假。。。[/quote] 如果你事先知道数组长度，求字符串数组的长度你需要调用strlen，那么求长度就已经遍历一次了。 这个主要判断是不是'\0'，因为'\0'等价0;0是假，那么！0就是真。[/quote] 嗯，我那个是常量字符数组，所以结尾可能不是‘\0’。。。谢谢您了。懂了[/quote] 如果不是字符串，建议也别用strchr，这个是针对字符串的函数。因此，若不是字符串，那么只能用字符个数作为循环遍历的结束条件，并且不能使用任何字符串的函数。

user: user-0
content: 引用 17 楼 zhao4zhong1 的回复:[code=c]#pragma comment(lib,"user32") 这是啥。。。。

user: user-0
content: 引用 15 楼 cfjtaishan 的回复:[quote=引用 14 楼 sys0613 的回复:] [quote=引用 12 楼 cfjtaishan 的回复:] [quote=引用 8 楼 sys0613 的回复:] [quote=引用 5 楼 cfjtaishan 的回复:] [quote=引用 2 楼 sys0613 的回复:] [quote=引用 1 楼 jianwen0529 的回复:] 可以，不过查找不到返回NULL，此刻要进行判断并处理  自己可以写一份函数，也就两三句代码的事情，重点是可以控制。比如判断两个参数的有效性，直接返回索引等等 嗯，写函数防止找不到的NULL，还需要控制别的么？？我其实主要是担心两个指针地址相减会不会偶发一些不兼容的问题。产生不可控制的错误？谢谢[/quote] 应该不会，因为strchr返回也是指向传入参数的相对地址，不会有不兼容的问题。要么找到，返回传入参数的某个字符位置的地址，要么返回NULL，未找到。  不用strchr可能会更好，因为想要的是某个字符所在的位置，那么直接遍历比较即可。若找到返回对应的位置，否则返回-1；通过自定义函数来得到；  #include <stdio.h>   int get_pos(const char *str, int key);  int main(void) {     const char *str = "helloworld";      printf("Pos = %d\n", get_pos(str, 'w'));      return 0; }  int get_pos(const char *str, int key) {     int i;     for (i = 0; str[i]; i++)         if (key == str[i])             break;      if (!str[i])         return -1;      return i; } 参考一下吧[/quote]  好的，谢谢了，自己写这种遍历和strchr哪个效率更好呢？我本身就有数组的长度。。我直接循环遍历可能比你这个还省事。。。[/quote] 还有比这个效率高的。可以贴出来，一起研究下； [/quote] 我是说我事先知道数组长度。。。我担心你那个  if (!str[i])，最后一位可能不是假。。。[/quote] 如果你事先知道数组长度，求字符串数组的长度你需要调用strlen，那么求长度就已经遍历一次了。 这个主要判断是不是'\0'，因为'\0'等价0;0是假，那么！0就是真。[/quote] 嗯，我那个是常量字符数组，所以结尾可能不是‘\0’。。。谢谢您了。懂了

user: user-3
content: 老赵嘚吧了半天一分没得，论坛玩的就是情怀...

user: user-1
content: 啥叫字符？啥叫字符串？

user: user-2
content: 引用 2 楼 sys0613 的回复:[quote=引用 1 楼 jianwen0529 的回复:] 可以，不过查找不到返回NULL，此刻要进行判断并处理  自己可以写一份函数，也就两三句代码的事情，重点是可以控制。比如判断两个参数的有效性，直接返回索引等等 嗯，写函数防止找不到的NULL，还需要控制别的么？？我其实主要是担心两个指针地址相减会不会偶发一些不兼容的问题。产生不可控制的错误？谢谢[/quote] 应该不会，因为strchr返回也是指向传入参数的相对地址，不会有不兼容的问题。要么找到，返回传入参数的某个字符位置的地址，要么返回NULL，未找到。  不用strchr可能会更好，因为想要的是某个字符所在的位置，那么直接遍历比较即可。若找到返回对应的位置，否则返回-1；通过自定义函数来得到；  #include <stdio.h>   int get_pos(const char *str, int key);  int main(void) {     const char *str = "helloworld";      printf("Pos = %d\n", get_pos(str, 'w'));      return 0; }  int get_pos(const char *str, int key) {     int i;     for (i = 0; str[i]; i++)         if (key == str[i])             break;      if (!str[i])         return -1;      return i; } 参考一下吧

user: user-4
content: 引用 2 楼 sys0613 的回复:[quote=引用 1 楼 jianwen0529 的回复:] 可以，不过查找不到返回NULL，此刻要进行判断并处理  自己可以写一份函数，也就两三句代码的事情，重点是可以控制。比如判断两个参数的有效性，直接返回索引等等 嗯，写函数防止找不到的NULL，还需要控制别的么？？我其实主要是担心两个指针地址相减会不会偶发一些不兼容的问题。产生不可控制的错误？谢谢[/quote] 不会，同类型指针+-这是C语法自带的规则，兼容性什么的不需要考虑

user: user-5
content: 不用系统函数，自己可以写一个，很简单啊，从字符串首指针开始，自增遍历，直到遇到结束符，定义一个int作为记录索引，初始为-1.在循环中也自增，然后在循环中判断当前字符是不是要查找的字符，是的话就返回索引就行了

user: user-0
content: 引用 1 楼 jianwen0529 的回复:可以，不过查找不到返回NULL，此刻要进行判断并处理  自己可以写一份函数，也就两三句代码的事情，重点是可以控制。比如判断两个参数的有效性，直接返回索引等等 嗯，写函数防止找不到的NULL，还需要控制别的么？？我其实主要是担心两个指针地址相减会不会偶发一些不兼容的问题。产生不可控制的错误？谢谢

user: user-4
content: 可以，不过查找不到返回NULL，此刻要进行判断并处理  自己可以写一份函数，也就两三句代码的事情，重点是可以控制。比如判断两个参数的有效性，直接返回索引等等

user: user-1
content: #pragma comment(lib,"user32") #pragma comment(lib,"gdi32") #include <conio.h> #include <stdio.h> #include <stdlib.h> #include <windows.h> extern "C" HWND WINAPI GetConsoleWindow(); void HideTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);      if(GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = FALSE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } void ShowTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);      if(GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = TRUE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } int main() {     HWND  hwnd;     HDC   hdc;     HFONT hfont;     wchar_t wc[2];      system("color F0");     system("cls");     HideTheCursor();     hwnd  = GetConsoleWindow();     hdc   = GetDC(hwnd);     hfont = CreateFont(48,0,0,0,0,0,0,0,GB2312_CHARSET ,0,0,0,0,"宋体-方正超大字符集");     SelectObject(hdc,hfont);     wc[0]=0xD854u;     wc[1]=0xDC00u;     TextOutW(hdc,10,10,wc,2);     DeleteObject(hfont);     ReleaseDC(hwnd,hdc);     getch();     system("color 07");     system("cls");     ShowTheCursor();     return 0; } #if 0 代理项或代理项对是一对共同表示单个字符的 16 位 Unicode 编码值。需要记住的关键一点是： 代理项对实际上是 32 位单个字符，不能再假定一个 16 位 Unicode 编码值正好映射到一个字符。  使用代理项对 代理项对的第一个值是高代理项，包含介于 U+D800 到 U+DBFF 范围内的 16 位代码值。 该对的第二个值是低代理项，包含介于 U+DC00 到 U+DFFF 范围内的值。通过使用代理项对， 16 位 Unicode 编码系统可以对已由 Unicode 标准定义的一百多万个其他字符 (220) 进行寻址。  在传递给 XmlTextWriter 方法的任何字符串中都可以使用代理项字符。不过，代理项字符在编写的 XML 中应该有效。例如，万维网联合会 (W3C) 建议不允许在元素或属性的名称中使用代理项字符。 如果字符串包含无效的代理项对，则引发异常。  另外，可以使用 WriteSurrogateCharEntity 写出与代理项对相对应的字符实体。字符实体以十六 进制格式写出，并用以下公式生成：  (highChar -0xD800) * 0x400 + (lowChar -0xDC00) + 0x10000  如果字符串包含无效的代理项对，则引发异常。下面的示例显示将代理项对作为输入的 WriteSurrogateCharEntity 方法。  C#复制  // The following line writes 𐀀. WriteSurrogateCharEntity ('\uDC00', '\uD800'); 下面的示例生成一个代理项对文件，将其加载到 XmlReader 中，并用新的文件名保存文件。 然后，原始文件和新文件被加载回应用程序的 XML 文档对象模型 (DOM) 结构中以进行比较。  C#复制  char lowChar, highChar; char [] charArray = new char[10]; FileStream targetFile = new FileStream("SurrogatePair.xml",       FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);  lowChar = Convert.ToChar(0xDC00); highChar = Convert.ToChar(0xD800); XmlTextWriter tw = new XmlTextWriter(targetFile, null); tw.Formatting = Formatting.Indented; tw.WriteStartElement("root"); tw.WriteStartAttribute("test", null); tw.WriteSurrogateCharEntity(lowChar, highChar); lowChar = Convert.ToChar(0xDC01); highChar = Convert.ToChar(0xD801); tw.WriteSurrogateCharEntity(lowChar, highChar); lowChar = Convert.ToChar(0xDFFF); highChar = Convert.ToChar(0xDBFF); tw.WriteSurrogateCharEntity(lowChar, highChar);  // Add 10 random surrogate pairs. // As Unicode, the high bytes are in lower // memory; for example, word 6A21 as 21 6A. // The high or low is in the logical sense. Random random = new Random(); for (int i = 0; i < 10; ++i) {       lowChar = Convert.ToChar(random.Next(0xDC00, 0xE000));       highChar = Convert.ToChar(random.Next(0xD800, 0xDC00));       charArray[i] = highChar;       charArray[++i] = lowChar; } tw.WriteChars(charArray, 0, charArray.Length);  for (int i = 0; i < 10; ++i) {       lowChar = Convert.ToChar(random.Next(0xDC00, 0xE000));       highChar = Convert.ToChar(random.Next(0xD800, 0xDC00));       tw.WriteSurrogateCharEntity(lowChar, highChar); }  tw.WriteEndAttribute(); tw.WriteEndElement(); tw.Flush(); tw.Close();  XmlTextReader r = new XmlTextReader("SurrogatePair.xml");  r.Read(); r.MoveToFirstAttribute(); targetFile = new FileStream("SurrogatePairFromReader.xml",        FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);  tw = new XmlTextWriter(targetFile, null); tw.Formatting = Formatting.Indented; tw.WriteStartElement("root"); tw.WriteStartAttribute("test", null); tw.WriteString(r.Value); tw.WriteEndAttribute(); tw.WriteEndElement(); tw.Flush(); tw.Close();  // Load both result files into the DOM and compare. XmlDocument doc1 = new XmlDocument(); XmlDocument doc2 = new XmlDocument(); doc1.Load("SurrogatePair.xml"); doc2.Load("SurrogatePairFromReader.xml"); if (doc1.InnerXml != doc2.InnerXml) {       Console.WriteLine("Surrogate Pair test case failed"); } 在使用 WriteChars 方法（一次写出一个缓冲区的数据）写出时，输入中的代理项对可能 会在一个缓冲区内被意外拆分。由于代理项值是定义完善的，如果 WriteChars 遇到来自 较低范围或者较高范围的 Unicode 值，它将该值标识为代理项对的一半。当遇到  WriteChars 将导致从拆分代理项对的缓冲区写入的情况时，将引发异常。使用   IsHighSurrogate 方法检查缓冲区是否以高代理项字符结束。如果缓冲区中的最后一个   字符不是高代理项，可以将该缓冲区传递给 WriteChars 方法。  请参见 概念 使用 XmlTextWriter 创建格式正确的 XML XmlTextWriter 的 XML 输出格式设置 XmlTextWriter 的命名空间功能  #endif

user: user-6
content: 没问题，同类型指针相减得到的就是元素个数，当然你也可以自己写个循环实现

user: user-2
content: 引用 14 楼 sys0613 的回复:[quote=引用 12 楼 cfjtaishan 的回复:] [quote=引用 8 楼 sys0613 的回复:] [quote=引用 5 楼 cfjtaishan 的回复:] [quote=引用 2 楼 sys0613 的回复:] [quote=引用 1 楼 jianwen0529 的回复:] 可以，不过查找不到返回NULL，此刻要进行判断并处理  自己可以写一份函数，也就两三句代码的事情，重点是可以控制。比如判断两个参数的有效性，直接返回索引等等 嗯，写函数防止找不到的NULL，还需要控制别的么？？我其实主要是担心两个指针地址相减会不会偶发一些不兼容的问题。产生不可控制的错误？谢谢[/quote] 应该不会，因为strchr返回也是指向传入参数的相对地址，不会有不兼容的问题。要么找到，返回传入参数的某个字符位置的地址，要么返回NULL，未找到。  不用strchr可能会更好，因为想要的是某个字符所在的位置，那么直接遍历比较即可。若找到返回对应的位置，否则返回-1；通过自定义函数来得到；  #include <stdio.h>   int get_pos(const char *str, int key);  int main(void) {     const char *str = "helloworld";      printf("Pos = %d\n", get_pos(str, 'w'));      return 0; }  int get_pos(const char *str, int key) {     int i;     for (i = 0; str[i]; i++)         if (key == str[i])             break;      if (!str[i])         return -1;      return i; } 参考一下吧[/quote]  好的，谢谢了，自己写这种遍历和strchr哪个效率更好呢？我本身就有数组的长度。。我直接循环遍历可能比你这个还省事。。。[/quote] 还有比这个效率高的。可以贴出来，一起研究下； [/quote] 我是说我事先知道数组长度。。。我担心你那个  if (!str[i])，最后一位可能不是假。。。[/quote] 如果你事先知道数组长度，求字符串数组的长度你需要调用strlen，那么求长度就已经遍历一次了。 这个主要判断是不是'\0'，因为'\0'等价0;0是假，那么！0就是真。

user: user-0
content: 引用 12 楼 cfjtaishan 的回复:[quote=引用 8 楼 sys0613 的回复:] [quote=引用 5 楼 cfjtaishan 的回复:] [quote=引用 2 楼 sys0613 的回复:] [quote=引用 1 楼 jianwen0529 的回复:] 可以，不过查找不到返回NULL，此刻要进行判断并处理  自己可以写一份函数，也就两三句代码的事情，重点是可以控制。比如判断两个参数的有效性，直接返回索引等等 嗯，写函数防止找不到的NULL，还需要控制别的么？？我其实主要是担心两个指针地址相减会不会偶发一些不兼容的问题。产生不可控制的错误？谢谢[/quote] 应该不会，因为strchr返回也是指向传入参数的相对地址，不会有不兼容的问题。要么找到，返回传入参数的某个字符位置的地址，要么返回NULL，未找到。  不用strchr可能会更好，因为想要的是某个字符所在的位置，那么直接遍历比较即可。若找到返回对应的位置，否则返回-1；通过自定义函数来得到；  #include <stdio.h>   int get_pos(const char *str, int key);  int main(void) {     const char *str = "helloworld";      printf("Pos = %d\n", get_pos(str, 'w'));      return 0; }  int get_pos(const char *str, int key) {     int i;     for (i = 0; str[i]; i++)         if (key == str[i])             break;      if (!str[i])         return -1;      return i; } 参考一下吧[/quote]  好的，谢谢了，自己写这种遍历和strchr哪个效率更好呢？我本身就有数组的长度。。我直接循环遍历可能比你这个还省事。。。[/quote] 还有比这个效率高的。可以贴出来，一起研究下； [/quote] 我是说我事先知道数组长度。。。我担心你那个  if (!str[i])，最后一位可能不是假。。。

user: user-3
content: 最快的方法，当然是再建立一个反向查找表，只需要初始化一次，之后可以直接映射，时间复杂度是O(1)。

user: user-2
content: 引用 8 楼 sys0613 的回复:[quote=引用 5 楼 cfjtaishan 的回复:] [quote=引用 2 楼 sys0613 的回复:] [quote=引用 1 楼 jianwen0529 的回复:] 可以，不过查找不到返回NULL，此刻要进行判断并处理  自己可以写一份函数，也就两三句代码的事情，重点是可以控制。比如判断两个参数的有效性，直接返回索引等等 嗯，写函数防止找不到的NULL，还需要控制别的么？？我其实主要是担心两个指针地址相减会不会偶发一些不兼容的问题。产生不可控制的错误？谢谢[/quote] 应该不会，因为strchr返回也是指向传入参数的相对地址，不会有不兼容的问题。要么找到，返回传入参数的某个字符位置的地址，要么返回NULL，未找到。  不用strchr可能会更好，因为想要的是某个字符所在的位置，那么直接遍历比较即可。若找到返回对应的位置，否则返回-1；通过自定义函数来得到；  #include <stdio.h>   int get_pos(const char *str, int key);  int main(void) {     const char *str = "helloworld";      printf("Pos = %d\n", get_pos(str, 'w'));      return 0; }  int get_pos(const char *str, int key) {     int i;     for (i = 0; str[i]; i++)         if (key == str[i])             break;      if (!str[i])         return -1;      return i; } 参考一下吧[/quote]  好的，谢谢了，自己写这种遍历和strchr哪个效率更好呢？我本身就有数组的长度。。我直接循环遍历可能比你这个还省事。。。[/quote] 还有比这个效率高的。可以贴出来，一起研究下；

user: user-7
content: 你的有长度可以同时判断 一个 word ( 32位机器上 4字节， 64位机器上 8 字节)  是否包含 ch， 比库函数能快一些， 不过， 这并没啥意义 ...

user: user-4
content: 摘自VS2013目录下.\VC\crt\src\strchr.c文件 /*** *strchr.c - search a string for a given character * *       Copyright (c) Microsoft Corporation. All rights reserved. * *Purpose: *       defines strchr() - search a string for a character * *******************************************************************************/  #include <cruntime.h> #include <string.h>  /*** *char *strchr(string, c) - search a string for a character * *Purpose: *       Searches a string for a given character, which may be the *       null character '\0'. * *Entry: *       char *string - string to search in *       char c - character to search for * *Exit: *       returns pointer to the first occurence of c in string *       returns NULL if c does not occur in string * *Exceptions: * *******************************************************************************/  char * __cdecl strchr (         const char * string,         int ch         ) {         while (*string && *string != (char)ch)                 string++;          if (*string == (char)ch)                 return((char *)string);         return(NULL); }

user: user-4
content: 引用 7 楼 sys0613 的回复:[quote=引用 4 楼 starytx 的回复:] 不用系统函数，自己可以写一个，很简单啊，从字符串首指针开始，自增遍历，直到遇到结束符，定义一个int作为记录索引，初始为-1.在循环中也自增，然后在循环中判断当前字符是不是要查找的字符，是的话就返回索引就行了 因为我这个需要频繁查找，数组长度基本为200，类型为char，用strchr会不会效率更高？这个函数会被调用很多很多次。用从头自增遍历效率慢不？[/quote] strchr的实现本身就是使用了遍历，你可以去看看编译器对其的实现代码