Иногда, когда в процессе dev есть обе рабочие станции WIN и системы LINUX (хостинг), а в коде вы не видите никакого вывода перед соответствующей строкой, это может быть форматирование файла и отсутствие Unix LF (linefeed) заканчивается.
Что мы обычно делаем, чтобы быстро исправить это, переименуйте файл, а в системе LINUX создайте новый файл вместо переименованного, а затем скопируйте его в него. Во многих случаях это решает проблему, так как некоторые из файлов, которые были созданы в WIN, когда-то перемещенные на хостинг, вызывают эту проблему.
Это исправление - это легкое исправление для сайтов, которыми мы управляем по FTP, и иногда может спасти наш новый членов команды некоторое время.
В1) Ваша версия atoi()
слишком проста, стандартная версия игнорирует начальные пробельные символы и обрабатывает необязательный знак перед числом. atoi(" -123junk")
следует оценить до -123
.
Q2) atoi
- это стандартная функция, определенная прототипом int atoi(const char *s);
, она возвращает целое число.
В3) В Code 2
есть несколько ошибок:
char
s
как i
, который неинициализирован. вместо этого вы должны определить массив с достаточно большим значением, таким как 64
, EOF
, чтобы остановить цикл в случае, если конец файла встречается без перевода строки. Вот модифицированная версия:
#include <stdio.h>
#include <stdlib.h>
int main() {
char s[64];
size_t i;
int c;
for (i = 0; i < sizeof(s) - 1 && (c = getchar()) != EOF;) {
s[i++] = c;
if (c == '\n')
break;
}
s[i] = '\0';
printf("%i", atoi(s));
return 0;
}
Q4) выражение n = 10 * n + (s[i] - '0')
вычисляется для каждой новой цифры, найденной в строке. Действительно, немного неэффективно умножать текущее значение на 10 до тех пор, пока не будет найдено ненулевой цифры, но написать функцию таким образом просто.
Чтобы избежать этих бесполезных умножений, вот альтернатива:
int atoi(const char *s) {
int n = 0;
size_t i = 0;
while (s[i] == '0')
i++;
if (s[i] >= '1' && s[i] <= '9') {
n = s[i++] - '0';
while (s[i] >= '0' && s[i] <= '9')
n = 10 * n + (s[i++] - '0');
}
return n;
}
Но эта функция более громоздка и может фактически быть менее эффективной, чем простая версия. Попробуйте и сравните тесты в вашей системе.
Для полноты, вот полная переносимая версия, использующая ctype.h>
, которая обрабатывает необязательный начальный пробел и необязательный знак. Он также обрабатывает переполнение с определенным поведением, хотя для этого не требуется стандартная версия atoi()
.
#include <limits.h>
#include <stdio.h>
int atoi(const char *s) {
int n = 0, d;
/* skip optional initial white space */
while (isspace((unsigned char)*s))
s++;
if (*s == '-') {
/* convert negative number */
s++;
while (isdigit((unsigned char)*s)) {
d = (*s++ - '0');
/* check for potential arithmetic overflow */
if (n < INT_MIN / 10 || (n == INT_MIN / 10 && -d < INT_MIN % 10)) {
n = INT_MIN;
break;
}
n = n * 10 - d;
}
} else {
/* ignore optional positive sign */
if (*s == '+')
s++;
while (isdigit((unsigned char)*s)) {
d = (*s++ - '0');
/* check for potential arithmetic overflow */
if (n > INT_MAX / 10 || (n == INT_MAX / 10 && d > INT_MAX % 10)) {
n = INT_MAX;
break;
}
n = n * 10 + d;
}
}
return n;
}
int main(int argc, char *argv[]) {
int i, n;
for (i = 1; i < argc; i++) {
n = atoi(argv[i]);
printf("\"%s\" -> %d\n", argv[i], n);
}
return 0;
}