【问题标题】:_stricmp returns wrong value while string DOES match. What to do?_stricmp 在字符串匹配时返回错误值。该怎么办?
【发布时间】:2012-02-21 21:45:52
【问题描述】:

我有这段代码:

                        second = strtok (NULL,"\n");
                        logprintf(second);
                        if(_stricmp(second,"WINDOWS") == 0)

logprintf 将数据打印到日志文件中,并打印“WINDOWS”(不带引号)。

但是 _stricmp 以某种方式返回 13.. 所以 if 检查永远不会通过。我尝试过使用 sscanf/sprintf/其他字符串方式,但没有任何效果。我没有想法。

完整代码:

#ifdef WIN32


char buf[65535];
bool found = false;
bool install = false;
bool installing = false;
unsigned int installed = 0;


WIN32_FIND_DATA fd;
HANDLE h = FindFirstFile(L"./*.AIFPAK", &fd);

char * NAME = NULL;
char * ID = NULL;
char * AUTHOR = NULL;
int VERSION;

HZIP hz = OpenZip(fd.cFileName,0);

ZIPENTRY ze; 
GetZipItem(hz,-1,&ze); 
int numitems=ze.index;
for (int i=0; i<numitems; ++i)
{ 
    GetZipItem(hz,i,&ze);

    if(found == false)
    {
        if(_wcsicmp(ze.name,L"INSTALL.AIFLIST") == 0)
        {
            found = true;
            UnzipItem(hz,i,buf,65535);
            i = 0;
            stringstream strx;
            strx << buf;
            string line;     
            while (getline(strx, line)) { 
                char * first = NULL;
                char * second = NULL;
                char * third = NULL;
                first = strtok ((char *)line.c_str()," ");
                if(install == false)
                {
                    if(_stricmp(first,"NAME") == 0)
                    {
                        NAME = strtok (NULL,"\n");
                    }
                    if(_stricmp(first,"ID") == 0)
                    {
                        ID = strtok (NULL,"\n");
                    }
                    if(_stricmp(first,"AUTHOR") == 0)
                    {
                        AUTHOR = strtok (NULL,"\n");
                    }
                    if(_stricmp(first,"VERSION") == 0)
                    {
                        VERSION = atoi(strtok (NULL,"\n"));
                    }
                    if(_stricmp(first,"START_INSTALL") == 0)
                    {
                        second = strtok (NULL,"\n");
                        logprintf(second);
                        if(_stricmp(second,"WINDOWS") == 0)
                        {
                            cout << "INSTALLAH\n";
                            install = true;
                            cout << NAME << "|" << ID << "|" << AUTHOR << "|" << VERSION << "|\n";
                        }
                    }
                }
                else
                {
                    cout << "ELSE FIRST: " << first << "\n";
                    if(_stricmp(first,"UNPACK") == 0)
                    {
                        second = strtok (NULL,">");
                        third = strtok (NULL,"\n");
                        cout << first << "|" << second << "|" << third << "|\n";
                        ToDoVec.push_back(ToDoInfo(0,second,third));
                    }
                    if(_stricmp(first,"PRINT") == 0)
                    {
                        second = strtok (NULL,"\n");
                        cout << first << "|" << second << "|" << third << "|\n";
                        ToDoVec.push_back(ToDoInfo(3,second,""));
                    }
                    if(_stricmp(first,"ADD_PLUGIN") == 0)
                    {
                        second = strtok (NULL,"\n");
                        cout << first << "|" << second << "|" << third << "|\n";
                        ToDoVec.push_back(ToDoInfo(1,second,""));
                    }
                    if(_stricmp(first,"ADD_FILTERSCRIPT") == 0)
                    {
                        second = strtok (NULL,"\n");
                        cout << first << "|" << second << "|" << third << "|\n";
                        ToDoVec.push_back(ToDoInfo(2,second,""));
                    }
                    if(_stricmp(first,"END_INSTALL") == 0)
                    {
                        break;
                    }
                }
            } 
        }
    }
    else
    {
        if(installing == false)
        {
            i = 0;
            installing = true;
            for(unsigned int ix = 0; ix < ToDoVec.size(); ++ix)
            {
                cout << "|" << ToDoVec.at(ix).action << "|" << ToDoVec.at(ix).string1 << "|" << ToDoVec.at(ix).string2 << "|\n";
            }
        }
        else
        {

        }
    }
}
found = false;
install = false;
installing = false
CloseZip(hz);

while (FindNextFile(h, &fd))
{
//fnVec.push_back(fd.cFileName);
}
#else//assuming linux

#endif

“INSTALL.AIFLIST”文件如下所示:

NAME Route Connector Plugin
ID GAMER_GPS
VERSION 1733
AUTHOR Gamer_Z

START_INSTALL WINDOWS

UNPACK RouteConnector/plugins/RouteConnectorPlugin.dll>./plugins/RouteConnectorPlugin.dll
UNPACK RouteConnector/examples/other/filterscripts/Node_GPS.amx>./filterscripts/Node_GPS.amx
UNPACK RouteConnector/examples/other/filterscripts/Node_GPS.pwn>./filterscripts/Node_GPS.pwn
UNPACK RouteConnector/scriptfiles/GPS.dat>./scriptfiles/GPS.dat
UNPACK RouteConnector/sampGDK/EXTRACTED/libsampgdk-2.2.1-win32/bin/sampgdk2.dll>./sampgdk2.dll

ADD_PLUGIN RouteConnectorPlugin
ADD_FILTERSCRIPT Node_GPS

END_INSTALL

START_INSTALL LINUX

UNPACK RouteConnector/plugins/RouteConnectorPlugin.so>./plugins/RouteConnectorPlugin.so
UNPACK RouteConnector/examples/other/filterscripts/Node_GPS.amx>./filterscripts/Node_GPS.amx
UNPACK RouteConnector/examples/other/filterscripts/Node_GPS.pwn>./filterscripts/Node_GPS.pwn
UNPACK RouteConnector/scriptfiles/GPS.dat>./scriptfiles/GPS.dat
PRINT To make this plugin work you must install the sampgdk library from www.github.com/Zeex/ (if you don't have it installed)

ADD_PLUGIN RouteConnectorPlugin.so
ADD_FILTERSCRIPT Node_GPS

END_INSTALL

所有数据都正确读入'buf'。

谁能建议如何解决这个问题?

【问题讨论】:

  • 变量中WINDOWS前后是否有空格?尝试使用“\n”作为标记进行 strtok(或者在打印它时,在其周围打印引号以确保。
  • 您找到了 std::stringgetline() 的用途。现在为什么哦,为什么你还在搞乱strtok_stricmp
  • 您在 c_str 返回的 const 字符串上调用 strtok。不要那样做。这是未定义的行为,它解释了程序中发生的任何其他奇怪的事情。找到一种不涉及以这种方式修改字符串的不同方式。
  • @RobKennedy 修改c_str() 返回的字符是未定义的行为,因为标准规定“程序不得更改存储在字符数组中的任何值”。这不是未定义的行为,因为它是 const 字符串:它可能根本不是 const
  • 已修复。谢谢,@Hvd。但是,当我说“const string”时,我指的是 const C 风格的字符串。 char const*.

标签: c++ c windows string compare


【解决方案1】:

看起来好像您没有考虑 CRLF 行尾。以文本模式打开文件会将“\r\n”转换为“\n”,但您的代码中没有任何内容可以这样做。如果“WINDOWS”后跟“\r\n”,您将其视为“WINDOWS\r”后跟“\n”,因为“\n”是您传递给strtok 的全部内容。有几种可能的解决方案,但一种是将“\r\n”传递给strtok

【讨论】:

    【解决方案2】:

    13 是回车符'\r',因此您的输入有一个尾随'\r',打印时不会显示。要删除它,请将"\r\n" 作为分隔符传递给strtok

    【讨论】:

      【解决方案3】:

      13 表示您的second 字符串包含"WINDOWS\r"\r 是回车符 - 在 Windows 上,文本文件中的行以 \r\n 序列终止,因此您的 getline() 函数似乎以 \n 终止并返回 \r 为字符串的一部分。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多