3

Интересно почему сразу заканчивается выполнение программы при попытке ввода дробных чисел с точкой, а не с запятой, хотя в самом коде используются точки? Не оставляю кода потому что считаю это бессмысленно? Кто-то может мне разъяснить этот вопрос?

7
  • Не могу воспроизвести, давайте код.
    – VladD
    11 апр 2013 в 7:34
  • 1
    @steelhouse, насколько понимаю, Вы начали изучать программирование на Си. Советую делать это в Linux и на первых порах не использовать русские буквы.
    – avp
    11 апр 2013 в 8:19
  • Он при этом ругается? как? скорее всего перед затрытием он пишет в консоль ошибку, но Вы ее не видите, так как консоль сразу закрывается. Попробуйте запустить через командную строку.
    – Zelta
    11 апр 2013 в 8:25
  • Просто для изучения программирования в Linux, нужно знать Linux, у меня пока времени на изучения OS нету.
    – Stee1House
    11 апр 2013 в 10:53
  • 1
    >Просто для изучения программирования в Linux, нужно знать Linux Совершенно не обязательно. Просто программирование в Linux вынуждает быть внимательней к мелочам и стандартам.
    – user6550
    11 апр 2013 в 11:05

1 ответ 1

18

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

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

void test(const char* str) {
  printf("%s => ", str); 
  char* endptr;
  double num = strtod(str, &endptr);
  // Checking if whole string parsed
  if (endptr != str + strlen(str)) {
    printf("ERROR");
  } else {
    printf("%lf", num);
  }
  printf("\n");
}

void locale_info() {
  printf("Current locale: %s\n", setlocale(LC_NUMERIC, NULL));
  printf("Current delimiter: '%s'\n", localeconv()->decimal_point);
}

int main() {
  const char* dot = "10.5";
  const char* comma = "10,5";
  setlocale(LC_ALL, "en_US.utf8");
  locale_info();
  test(dot);
  test(comma);
  setlocale(LC_ALL, "ru_RU.utf8");
  locale_info();
  test(dot);
  test(comma);
}

У меня программа выводит:

Current locale: en_US.utf8
Current delimiter: '.'
10.5 => 10.500000
10,5 => ERROR
Current locale: ru_RU.utf8
Current delimiter: ','
10.5 => ERROR
10,5 => 10,500000

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

setlocale(LC_NUMERIC, "C");
4
  • 1
    отличный ответ, почему только 2 плюса?
    – VladD
    11 апр 2013 в 9:10
  • Некогда читать все.
    – avp
    11 апр 2013 в 9:17
  • 1
    Спасибо за ответ. Очень доходчиво написано.
    – Stee1House
    11 апр 2013 в 11:02
  • программы стартуют в C локале, поэтому не нужно вызывать setlocale(LC_NUMERIC, "C"); если других setlocale в программе нет. В общем случае (не к этому вопросу) setlocale может не иметь эффекта на с++ функции.
    – jfs
    10 ноя 2014 в 12:37

Ваш ответ

By clicking “Отправить ответ”, you agree to our terms of service and acknowledge you have read our privacy policy.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками или задайте свой вопрос.