sprintf () и WriteFile () влияют на строковый буфер - PullRequest
1 голос
/ 09 ноября 2008

У меня очень странная проблема, которую я не могу понять. К сожалению, я даже не уверен, как описать это, не описав всю мою заявку. То, что я пытаюсь сделать, это:

1) read a byte from the serial port
2) store each char into tagBuffer as they are read
3) run a query using tagBuffer to see what type of tag it is (book or shelf tag)
4) depending on the type of tag, output a series of bytes corresponding to the type of tag

Большая часть моего кода реализована, и я могу получить правильный код тега, отправленный обратно через последовательный порт. Но есть две строки, которые я добавил как операторы отладки, которые, когда я пытался удалить их, приводили к тому, что моя программа перестала работать.

Строки - это две строки в самом низу: </p> <pre><code> sprintf(buf,"%s!\n", tagBuffer); WriteFile(hSerial,buf,strlen(buf), &dwBytesWritten,&ovWrite);

Если я попытаюсь удалить их, «tagBuffer» будет хранить только последний символ, а не буфер. То же самое со следующей строкой, WriteFile ().

Я думал, что sprintf и WriteFile являются функциями ввода-вывода и не будут влиять на переменные. Я застрял и мне нужна помощь, чтобы это исправить.

</p> <pre><code>//keep polling as long as stop character '-' is not read while(szRxChar != '-') { // Check if a read is outstanding if (HasOverlappedIoCompleted(&ovRead)) { // Issue a serial port read if (!ReadFile(hSerial,&szRxChar,1, &dwBytesRead,&ovRead)) { DWORD dwErr = GetLastError(); if (dwErr!=ERROR_IO_PENDING) return dwErr; } } // resets tagBuffer in case tagBuffer is out of sync time_t t_time = time(0); char buf[50]; if (HasOverlappedIoCompleted(&ovWrite)) { i=0; } // Wait 5 seconds for serial input if (!(HasOverlappedIoCompleted(&ovRead))) { WaitForSingleObject(hReadEvent,RESET_TIME); } // Check if serial input has arrived if (GetOverlappedResult(hSerial,&ovRead, &dwBytesRead,FALSE)) { // Wait for the write GetOverlappedResult(hSerial,&ovWrite, &dwBytesWritten,TRUE); if( strlen(tagBuffer) >= PACKET_LENGTH ) { i = 0; } //load tagBuffer with byte stream tagBuffer[i] = szRxChar; i++; tagBuffer[i] = 0; //char arrays are \0 terminated //run query with tagBuffer sprintf(query,"select type from rfid where rfidnum=\""); strcat(query, tagBuffer); strcat(query, "\""); mysql_real_query(&mysql,query,(unsigned int)strlen(query)); //process result and send back to handheld res = mysql_use_result(&mysql); while(row = mysql_fetch_row(res)) { printf("result of query is %s\n",row[0]); string str = ""; str = string(row[0]); if( str == "book" ) { WriteFile(hSerial,BOOK_INDICATOR,strlen(BOOK_INDICATOR), &dwBytesWritten,&ovWrite); } else if ( str == "shelf" ) { WriteFile(hSerial,SHELF_INDICATOR,strlen(SHELF_INDICATOR), &dwBytesWritten,&ovWrite); } else //this else doesn't work { WriteFile(hSerial,NOK,strlen(NOK), &dwBytesWritten,&ovWrite); } } mysql_free_result(res); // Display a response to input //printf("query is %s!\n", query); //printf("strlen(tagBuffer) is %d!\n", strlen(tagBuffer)); //without these, tagBuffer only holds the last character sprintf(buf,"%s!\n", tagBuffer); WriteFile(hSerial,buf,strlen(buf), &dwBytesWritten,&ovWrite); } }

С этими двумя строками мой вывод выглядит так: s sh she shel полка полка0 полка00 BOOKCODE полка0001

Без них я понял, что tagBuffer и buf одновременно хранят только самый последний символ.

Любая помощь будет принята с благодарностью. Спасибо.

Ответы [ 4 ]

1 голос
/ 09 ноября 2008

Кажется маловероятным, что эти две строки окажут такое влияние на правильную программу - может быть, вы не выделили достаточно места в buf для всей длины строки в tagBuffer? Это может вызвать переполнение буфера, скрывающее реальную проблему?

1 голос
/ 09 ноября 2008

Первое, что я бы сказал, это общий совет: ошибки не всегда там, где вы думаете. Если у вас что-то происходит, что, кажется, не имеет смысла, это часто означает, что ваши предположения где-то еще неверны.

Здесь очень маловероятно, что sprintf () и WriteFile () изменят состояние переменной массива "buf". Однако эти две строки тестового кода записывают в «hSerial», в то время как ваш основной цикл также читает из «hSerial». Это звучит как получатель за изменение поведения вашей программы.

Предложение. Измените строки вывода отладочной информации, чтобы сохранить результаты в другом месте: в диалоговом окне, в файле журнала или аналогичном. Вывод отладочной информации, как правило, не должен идти к файлам, используемым в логике ядра, так как это слишком вероятно изменит поведение логики ядра.

1 голос
/ 09 ноября 2008

Где вы размещаете tagbuffer, насколько он велик?
Возможно, вы перезаписываете «buf», потому что пишете после конца тегового буфера.

0 голосов
/ 09 ноября 2008

На мой взгляд, реальная проблема здесь в том, что вы пытаетесь читать и записывать последовательный порт из одного потока, и это делает код более сложным, чем нужно. Я предлагаю вам прочитать следующие статьи и пересмотреть свой дизайн:

В многопоточной реализации всякий раз, когда поток чтения читает сообщение из последовательного порта, вы затем отправляете его в основной поток вашего приложения. Затем основной поток проанализирует сообщение и запросит базу данных, а затем поставит в очередь соответствующий ответ потоку записи.

Это может показаться более сложным, чем ваш текущий дизайн, но на самом деле это не так, как объясняет новичок.

Надеюсь, это поможет!

...