2013-11-20 5 views
3

Для осуществления моих навыков программирования в C я пытаюсь написать функцию strncpy самостоятельно. Делая это, я продолжал сталкиваться с ошибками, решая большинство из них, в конечном итоге я застрял без дальнейшего вдохновения.Формат '% s' ожидает аргумент типа 'char *'

Ошибка я получаю это:

ex2-1.c:29:3: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=] 
    printf("The copied string is: %s.\n", stringb); 

Дело в том, что это очень распространенная ошибка, и что это также уже описано на SO, только я не могу применить советы других людей уже указывали вне. Я получаю, что при печати переменной я использую неправильный тип, и когда я использую формат% d, он возвращает целое число, которое, вероятно, является значением ASCII первого символа, поскольку оно не изменяется при увеличении максимального числа байтов для копирования.

Использование GDB Я обнаружил, что переменная b, когда выполняется итерация через цикл while, содержит правильную строку, но я не могу ее напечатать.

Возможно, мне не хватает фундаментальной части знаний о языке С, и я прошу прощения за задание этого нового вопроса (еще раз). Также я был бы признателен, если бы вы могли дать отзыв или указать другие недостатки в моем коде.

#include <stdlib.h> 
#include <stdio.h> 

void strmycpy(char **a, char *b, int maxbytes) { 
    int i = 0; 
    char x = 0; 

    while(i!=maxbytes) { 
    x = a[0][i]; 
    b[i] = x; 
    i++; 
    } 

    b[i] = 0; 

} 


int main (int argc, char **argv) { 
    int maxbytes = atoi(argv[2]); 
    //char stringa; 
    char stringb; 
    if (argc!=3 || maxbytes<1) { 
     printf("Usage: strmycpy <input string> <numberofbytes>. Maxbytes has to be more than or equal to 1 and keep in mind for the NULL byte (/0).\n"); 
     exit(0); 
    } else { 

    strmycpy(&argv[1], &stringb, maxbytes); 
    printf("The copied string is: %s.\n", stringb); 

    } 

    return 0; 
} 
+2

'stringb' является' char', а не 'char *'. – Zeta

+1

'stringb' - это символ (который передается в int при передаче' printf() '). Вам нужно объявить его как массив подходящего размера. Действительно, «еще раз». –

+0

'% s' требует адрес символьной последовательности, который завершается с помощью nul-char. Вы передаете символ, а не адрес последовательности символов, и, конечно, не тот, который заканчивается с помощью nul-char. – WhozCraig

ответ

6

Существует небольшая разница между char и char*. Первый - это один символ, тогда как более поздний - указатель на char (который может указывать на переменное число объектов char).

Спецификатор формата %s действительно ожидает строку C-стиля, которая должна быть не только типа char*, но также ожидается, что она будет завершена с нулевой отметкой (см. C string handling). Если вы хотите напечатать один символ, используйте вместо этого %c.

Что касается программы, при условии, что то, что я думаю, что вы хотите, что вы хотите, попробовать что-то вроде этого:

#include <stdlib.h> 
#include <stdio.h> 
#include <assert.h> 

static void strmycpy(char *dest, const char *src, size_t n) { 
    char c; 
    while (n-- > 0) { 
     c = *src++; 
     *dest++ = c; 
     if (c == '\0') { 
      while (n-- > 0) 
       *dest++ = '\0'; 
      break; 
     } 
    } 
} 

int main(int argc, char *argv[]) { 
    size_t maxbytes; 
    char *stringb; 

    if (argc != 3 || !(maxbytes = atoll(argv[2]))) { 
     fprintf(
      stderr, 
      "Usage: strmycpy <input string> <numberofbytes>.\n" 
      "Maxbytes has to be more than or equal to 1 and keep " 
      "in mind for the null byte (\\0).\n" 
     ); 
     return EXIT_FAILURE; 
    } 

    assert(maxbytes > 0); 
    if (!(stringb = malloc(maxbytes))) { 
     fprintf(stderr, "Sorry, out of memory\n"); 
     return EXIT_FAILURE; 
    } 

    strmycpy(stringb, argv[1], maxbytes); 
    printf("The copied string is: %.*s\n", (int)maxbytes, stringb); 
    free(stringb); 

    return EXIT_SUCCESS; 
} 

Но, честно говоря, это так важно, чтобы объяснить может только привести в написании книги на C. Так что вам будет намного лучше, если вы просто прочтете уже написанное. Список хороших книг и ресурсов C см. The Definitive C Book Guide and List

Надеюсь, это поможет. Удачи!

+3

* Незначительный *? Sry. это заставило меня рассмеяться. – WhozCraig

+2

@WhozCraig: Да, разница только в звездочке, насколько велика она может быть прав :) –

+1

Разница незначительна. : P –