sprintf не работает самопроизвольно в зависимости от того, какие вызовы printf и NSLog существуют - PullRequest
0 голосов
/ 01 сентября 2010

Здравствуйте, у меня странная проблема с sprintf. Вот мой код:

void draw_number(int number,int height,int xpos,int ypos){
    char string_buffer[5]; //5000 is the maximum score, hence 4 characters plus null character equals 5
    printf("Number - %i\n",number);
    sprintf(string_buffer,"%i",number); //Get string
    printf("String - %s\n",string_buffer);
    int y_down = ypos + height;
    for (int x = 0; x < 5; x++) {
        char character = string_buffer[x];
        if(character == NULL){ //Blank characters occur at the end of the number from spintf. Testing with NULL works
            break;
        }
        int x_left = xpos+height*x;
        int x_right = x_left+height;
        GLfloat vertices[] = {x_left,ypos,x_right,ypos,x_left,y_down,x_right,y_down};
        rectangle2d(vertices, number_textures[atoi(strcat(&character,"\0"))], full_texture_texcoords);
    }
}

При вызовах printf номера печатаются успешно, а номера выводятся, как ожидается Когда я убираю их, я, конечно, не могу просмотреть вывод и сравнить его, но числа отображаются неправильно. Я предполагаю, что sprintf как-то ломается.

Это также происходит с NSLog. Добавление NSLog в любую точку программы может привести к поломке или исправлению функции.

Что происходит на земле?

Используется Objective-C с iOS 4 SDK.

Спасибо за любой ответ.

Ответы [ 4 ]

4 голосов
/ 01 сентября 2010

Ну, этот бит кода определенно нечетен

char character = string_buffer[x]; 
...
... strcat(&character,"\0") ...

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

Возможно, содержимое стека на самом деле содержит числа, которые atoi интерпретирует? В любом случае, я предлагаю вам исправить это.и посмотрим, решит ли это вашу проблему.

Что касается того, как это исправить? Георг Фрицше опередил меня.

2 голосов
/ 01 сентября 2010

С strcat(&character,"\0") вы пытаетесь использовать один символ в качестве массива символов.Это, вероятно, приведет к тому, что atoi() вернет полностью отличающиеся значения от ожидаемых (так как у вас нет нулевого завершения) или просто завершится сбоем.

Чтобы исправить исходный подход, вы можете использовать собственно ноль-завершенная строка:

char number[] = { string_buffer[x], '\0' };
// ...
... number_textures[atoi(number)] ...

Но еще проще было бы просто использовать следующее:

... number_textures[character - '0'] ...
1 голос
/ 01 сентября 2010

Если у вас возникла такая проблема, немедленно подумайте о повреждении стека или кучи.Вы должны динамически распределять ваш буфер с достаточным размером - иметь фиксированный размер, который НАЧИНАЕТСЯ для такого рода проблем.Поскольку вы не проверяете, что число находится в пределах максимума, - если у вас когда-либо была другая ошибка, из-за которой она превышала максимум, вы получите эту проблему здесь.

1 голос
/ 01 сентября 2010

Не используйте NULL для сравнения с символом, используйте '\ 0', так как это символ, который вы ищете. Кроме того, ваш комментарий к коду звучит удивленно, разумеется, в конце строки будет отображаться '\ 0', то есть, как C завершает строки.

Если ваш номер превышает 9999, у вас будет переполнение буфера, которое может привести к непредсказуемым последствиям.

...