Atoi си реализация - IT Справочник
Llscompany.ru

IT Справочник
20 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Atoi си реализация

Напишите свой собственный atoi ()

Функция atoi () в C принимает строку (которая представляет целое число) в качестве аргумента и возвращает ее значение типа int. Таким образом, в основном функция используется для преобразования строкового аргумента в целое число.

Синтаксис:

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

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

Пример:

#include
#include
#include

char strn1[] = «12546» ;

val = atoi (strn1);

printf ( «String value = %sn» , strn1);

printf ( «Integer value = %dn» , val);

char strn2[] = «GeeksforGeeks» ;

val = atoi (strn2);

printf ( «String value = %sn» , strn2);

printf ( «Integer value = %dn» , val);

Выход:

Теперь давайте разберемся, как можно создать собственную функцию atoi (), поддерживаемую различными условиями:

    Ниже приводится простая реализация преобразования без учета какого-либо особого случая. Мы инициализируем результат как 0. Мы начинаем с первого символа и обновляем результат для каждого символа. С

// Программа для реализации atoi () в C
#include

// Простая функция atoi ()

int myAtoi( char * str)

int res = 0; // Инициализировать результат

// перебираем все символы входной строки и

for ( int i = 0; str[i] != ‘’ ; ++i)

res = res * 10 + str[i] — ‘0’ ;

// Программа драйвера для проверки вышеуказанной функции

char str[] = «89789» ;

int val = myAtoi(str);

printf ( «%d » , val);

// Простая C ++ программа для реализации atoi
#include

using namespace std;

// Простая функция atoi ()

int myAtoi( char * str)

int res = 0; // Инициализировать результат

// перебираем все символы входной строки и

for ( int i = 0; str[i] != ‘’ ; ++i)

res = res * 10 + str[i] — ‘0’ ;

char str[] = «89789» ;

int val = myAtoi(str);

// Это код, предоставленный rathbhupendra

# Python программа для реализации atoi

# Простая функция atoi ()

# Перебирать все символы входной строки и

for i in xrange ( len (string)):

res = res * 10 + ( ord (string[i]) — ord ( ‘0’ ))

# Этот код предоставлен BHAVYA JAIN

// Простая программа на C # для реализации
// из Атои

// Простая функция atoi ()

static int myAtoi( string str)

int res = 0; // Инициализировать результат

// Перебираем все символы

// вводим строку и обновляем результат

for ( int i = 0; i

res = res * 10 + str[i] — ‘0’ ;

// Программа драйвера для проверки вышеуказанной функции

public static void Main()

string str = «89789» ;

int val = myAtoi(str);

// Этот код предоставлен Sam007.

Выход:

В приведенной ниже реализации обработаны отрицательные числа.
C ++

// C ++ программа для реализации atoi
#include

using namespace std;

// Простая функция atoi ()

int myAtoi( char * str)

int res = 0; // Инициализировать результат

int sign = 1; // Инициализировать знак как положительный

int i = 0; // Инициализируем индекс первой цифры

// Если число отрицательное, то обновляем знак

i++; // Также обновляем индекс первой цифры

// Перебираем все цифры и обновляем результат

for (; str[i] != ‘’ ; ++i)

res = res * 10 + str[i] — ‘0’ ;

// Возвращаем результат со знаком

return sign * res;

int val = myAtoi(str);

// Это код, предоставленный rathbhupendra

// AC программа для реализации атои
#include

// Простая функция atoi ()

int myAtoi( char * str)

int res = 0; // Инициализировать результат

int sign = 1; // Инициализировать знак как положительный

int i = 0; // Инициализируем индекс первой цифры

// Если число отрицательное, то обновляем знак

i++; // Также обновляем индекс первой цифры

// Перебираем все цифры и обновляем результат

for (; str[i] != ‘’ ; ++i)

res = res * 10 + str[i] — ‘0’ ;

// Возвращаем результат со знаком

return sign * res;

// Программа драйвера для проверки вышеуказанной функции

int val = myAtoi(str);

printf ( «%d » , val);

# Python программа для реализации atoi

# Простая функция atoi ()

# инициализировать знак как положительный

# если число отрицательное, обновите знак

# Перебирать все символы входной строки и обновлять результат

for j in xrange (i, len (string)):

res = res * 10 + ( ord (string[j]) — ord ( ‘0’ ))

return sign * res

# Этот код предоставлен BHAVYA JAIN

// C # программа для реализации atoi

// Простая функция atoi ()

static int myAtoi( string str)

// Инициализировать знак как положительный

// Инициализируем индекс первой цифры

// Если число отрицательное, то

// Также обновляем индекс первого

// перебирать все цифры

// и обновляем результат

res = res * 10 + str[i] — ‘0’ ;

// Возвращаем результат со знаком

return sign * res;

// Программа драйвера для проверки вышеуказанной функции

public static void Main()

string str = «-123» ;

int val = myAtoi(str);

// Этот код предоставлен Sam007.

Выход:

Эта реализация обрабатывает различные типы ошибок . Что если str равен NULL или str содержит нечисловые символы. Следующая реализация обрабатывает ошибки .
C ++

// Простая C ++ программа для реализации atoi

// Утилита для проверки, является ли x числовым

bool isNumericChar( char x)

// Простая функция atoi (). Если данная строка содержит
// любой недопустимый символ, тогда эта функция возвращает 0

int myAtoi( char * str)

int res = 0; // Инициализировать результат

int sign = 1; // Инициализировать знак как положительный

int i = 0; // Инициализируем индекс первой цифры

// Если число отрицательное, то обновляем знак

i++; // Также обновляем индекс первой цифры

// Перебираем все цифры входной строки и обновляем результат

for (; str[i] != ‘’ ; ++i) <

if (isNumericChar(str[i]) == false )

return 0; // Вы можете добавить несколько строк, чтобы написать сообщение об ошибке

res = res * 10 + str[i] — ‘0’ ;

// Возвращаем результат со знаком

return sign * res;

// Программа драйвера для проверки вышеуказанной функции

int val = myAtoi(str);

printf ( «%d » , val);

# Python программа для реализации atoi

# Полезная функция для проверки, является ли x числовым

if (x > = ‘0’ and x = ‘9’ ):

# Простая функция atoi (). Если данная строка содержит
# любой недопустимый символ, тогда эта функция возвращает 0

if len (string) = = 0 :

# инициализировать знак как положительный

# если число отрицательное, обновите знак

# Перебирать все символы входной строки и обновлять результат

for j in xrange (i, len (string)):

# Вы можете добавить несколько строк для записи сообщения об ошибке в поток ошибок

if isNumericChar(string[j] = = False ):

res = res * 10 + ( ord (string[j]) — ord ( ‘0’ ))

return sign * res

# Этот код предоставлен BHAVYA JAIN

Сложность времени: O (n) где n — количество символов во входной строке.

Нам нужно обработать только четыре случая:

  • Отбрасывает все ведущие пробелы
  • знак числа
  • переполнение
  • Неверный Ввод

Ниже приведен пробный запуск вышеуказанного подхода:

Ниже приведена реализация вышеуказанного подхода:

// Простая C ++ программа для реализации atoi
#include

using namespace std;

int myAtoi( const char * str)

int sign = 1, base = 0, i = 0;

// если пробелы, то игнорировать.

sign = 1 — 2 * (str[i++] == ‘-‘ );

// проверка правильности ввода

while (str[i] >= ‘0’ && str[i] ‘9’ ) <

// обработка теста переполнения

if (base > INT_MAX / 10 || (base == INT_MAX / 10 && str[i] — ‘0’ > 7)) <

base = 10 * base + (str[i++] — ‘0’ );

return base * sign;

int val = myAtoi(str);

printf ( «%d » , val);

>
// Этот код предоставлен Йогеш Шукла.

Выход :

Сложность времени O (n), где n — длина строки.

Упражнение
Напишите свой выигранный atof (), который принимает строку (которая представляет значение с плавающей запятой) в качестве аргумента и возвращает его значение как double.

реализация atoi в C++

Учитывая эту реализацию atoi в C++

Как именно работает линия

Измените строку цифр на значения int? (Честно говоря, я довольно ржавый с C++. )

4 Ответов

Стандарт требует, чтобы цифры были последовательными в наборе символов. Это означает, что вы можете использовать:

Чтобы перевести значение символа в его эквивалентное числовое значение.

Часть res * 10 состоит в том, чтобы перетасовать оставшиеся цифры в общей сумме, чтобы освободить место для новой цифры, которую вы вставляете.

Например, если вы передадите «123» в эту функцию, res будет 1 после первой итерации цикла, затем 12 и, наконец, 123 .

Каждый шаг этой линии делает две вещи:

  1. Сдвигает всю цифру влево на место в десятичной системе счисления
  2. Помещает текущую цифру в нужное место

Часть str[i] — ‘0’ принимает символ ASCII соответствующей цифры, которые являются последовательно «0123456789» и вычитает код для ‘0’ из текущего символа. Это оставляет число в диапазоне 0..9 относительно того, какая цифра находится в этом месте в строке.

Читать еще:  При подготовке к установке произошла ошибка

Поэтому, глядя на ваш пример, произойдет следующее:

  1. i = 0 → str[i] = ‘8’ : res = 0 * 10 + 8 = 8
  2. i = 1 → str[i] = ‘9’ : res = 8 * 10 + 9 = 89
  3. i = 2 → str[i] = ‘7’ : res = 89 * 10 + 7 = 897
  4. i = 3 → str[i] = ‘8’ : res = 897 * 10 + 8 = 8978
  5. i = 4 → str[i] = ‘9’ : res = 8978 * 10 + 9 = 89789

И вот вам результат.

Цифры 0123456789 являются последовательными в ASCII.

Тип char (и в буквальном char как ‘0’ ) являются целыми числами. В этом случае ‘0’ эквивалентно 48 . Вычитание этого смещения даст вам цифру в числовой форме.

Давайте возьмем пример:

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

теперь, поскольку каждая буква в «234» на самом деле является символом, а не int и имеет значение ASCII, связанное с ним

если бы я сделал это:

тогда я бы получил 5562, чего мы не хотим.

помните : при использовании символов в арифметических выражениях используется их значение ASCII (автоматическая типизация char — > int). Следовательно, нам нужно преобразовать символ ‘2’ (50) в int 2, что мы можем сделать следующим образом:

Давайте решим его снова с этой коррекцией:

234-это необходимый ответ

Похожие вопросы:

Я пытаюсь прочитать некоторые входные данные в программе C, но по какой-то причине atoi возвращает -1 . Я делаю что-то не так? Выполните мое мнение и мой код: Ввод .

В программировании C я действительно путаюсь с функцией atoi. Я также могу написать так: atoi(years) = age; вместо : age = atoi(years); . Первый дает предупреждение, но все равно работает как.

Является ли atoi() частью стандарта C? Что я должен использовать для преобразования char* в int , если atoi() не стандартизирован?

У меня есть некоторые проблемы с примером функции atoi() из K&R C 2-го издания. Следует использовать только символы от 0 до 9. Но где-то в логике моей программы я делаю что-то не так. Так что.

Я хочу преобразовать строку в целое число. Но моя строка 234,23,34,45.If я использую atoi, он дает мне только 234.I хочу конвертировать все целые числа в моей строке. Как я могу использовать atoi.

Я заблудился здесь. Какова его цель? Взять строку и сделать ее int? Или преобразовать символ в ASCII? Если я использую любое число для char s[], я получаю это число обратно. Если я использую любую.

Есть ли функция, которая могла бы заменить atoi в c++? Я провел некоторые исследования и не нашел ничего, что могло бы заменить его, единственными решениями были бы использование cstdlib или.

У меня есть следующая функция в C++: #include #include #include bool isPrime(char myArr[]) < int myInt=atoi(myArr); int maxX=sqrt(myInt)+1; for(int.

Я новичок в C++, что я могу сделать, чтобы выполнить что — то вроде getline(textfile, txtline) int i = 0; while (textline[i] != ‘ ‘) //until space < if (isdigit(txtline[i]) == true) int n =.

Я хотел бы попробовать написать реализацию atoi с использованием инструкций SIMD, которые будут включены в RapidJSON (библиотека чтения/записи C++ JSON). В настоящее время он имеет некоторые SSE2 и.

Создание функции atoi

Я пытаюсь создать свою собственную функцию atoi. При следующем я получаю возвращаемое значение 0. Независимо от того, что я изменяю, числовая переменная внутри функции — это то, что я получаю как возвращаемое значение. Любые предложения по изменению кода?

c function atoi

5 ответов

8 Решение Carl Norum [2013-04-17 21:09:00]

Вы объявляете массив char * , то есть массив строк, а не одну строку. Вероятно, вы хотите:

Строка формата scanf неверна. Если вы хотите прочитать строку, вы должны использовать %s . %c читает только один символ.

Неверный параметр scanf — сам number (или &number[0] , если вы предпочитаете), а не &number .

Параметр, который вы передаете в atoi_me , неверен. Назовите его number (или эквивалентно &number[0] ), а не *number .

Объединяя все это, вы должны иметь подпрограмму main что-то вроде этого:

Редакционные примечания: у вас есть потенциальное переполнение буфера с помощью строки scanf . Вам будет лучше использовать функцию типа fgets(3) , которая упрощает защиту от этой проблемы.

atoi(3) также традиционно поддерживает отрицательные числа (с ведущим — ) и необязательным ведущим + для положительных чисел, что ваша реализация не обрабатывается.

Как я думал, проблема в вашем вызове.

Измените свой основной.

Кроме этого, неплохо использовать scanf — http://c-faq.com/stdio/scanfprobs.html. В этом случае вы должны использовать fgets .

1 jxh [2013-04-17 21:32:00]

Это не проблема с вашей функцией atoi_me() , но проблема с тем, как вы получили свой ввод. Ваша реализация показывает некоторую слабость в понимании того, как работает scanf() . Это не проблема сама по себе, допуская ошибки, является частью процесса обучения.

Как правило, безопаснее сначала собирать ваш вход в буфер, потому что scanf() со стандартного ввода слишком сильно зависит от пользователя программы, чтобы вводить ввод точно так, как вы ожидаете. В этом случае нет большого вреда, поскольку вам нужна только одна строка ввода. Но, как правило, программа будет обрабатывать несколько строк ввода, а scanf() может замяться при возникновении ошибки. Итак, вы можете использовать что-то вроде этого, чтобы получить свою строку ввода:

Как упоминалось в другом месте, %c является неправильным спецификатором формата, который будет использоваться для ввода, который вы собираете. Поскольку вы хотите десятичные цифры, семейство *scanf() имеет спецификатор формата, позволяющий собирать только эти символы.

Здесь я использую line , который был извлечен с помощью fgets() , и проанализируйте часть ввода, содержащую цифры. Ведущее пространство заставляет sscanf() пропускать символы пробела, ведущие к цифрам.

0 Fabien [2013-04-17 21:10:00]

Так как number должен быть массивом char,

  • вы должны объявить его как char number[MAXSIZE]; ,
  • вы не должны вызывать свою функцию с помощью &number , но с помощью number , непосредственно: atoi_me(number);

Лучше использовать указатель типа const, так как вы не собираетесь изменять содержимое строки.

How does atoi() function in C++ work?

So. I know that the atoi function in the C++ standard library is supposed to convert a string into an integer. how does it work. (I’m trying to learn stuff and I was just wondering). if you could show me the code from it or make your own that would do the same task it’d be greatly appreciated. thanks in advance.

Создан 18 апр. 11 2011-04-18 23:48:18 JacKeown

7 ответов

Something like this:

You loop through the characters in the string as long as they are digits. For each one, add to the counter you’re keeping — the value to add is the integer value of the character. This is done by subtracting the ascii value of ‘0’ from the ascii value of the digit in question.

Note that this code doesn’t handle overflow. If you pass in «887452834572834928347578423485273» (which won’t fit in an int ), the result is undefined.

you forgot to do ‘value *= 10;’ at the top of the loop. – Tim 18 апр. 11 2011-04-18 23:54:55

This sums the digits instead of producing the number. – JaredPar 18 апр. 11 2011-04-18 23:55:06

Oops, thanks @Tim. Fixed. – Graeme Perrow 18 апр. 11 2011-04-18 23:56:11

+1 for ‘c++’ in your code. – Marlon 19 апр. 11 2011-04-19 00:06:36

But note that there can be an optional plus/minus sign before the digits that is not handled by this code. Int is a signed type. – hubalu 07 сен. 13 2013-09-07 12:21:47

Fixed to handle an optional +/- at the beginning. Maybe that will satisfy the drive-by downvoters. – Graeme Perrow 18 дек. 13 2013-12-18 18:39:38

The logic is simply to process each character into it’s integer value (adjusting for position within the string).

Here’s how I did it in C#. Same general idea.

Turn the question around: how do you do it? When you see «31» written down, how do you understand how many of X you need to count out to equal that?

Читать еще:  C1 6775 5 ошибка

Well, you can code that up.

Actually is is often implemented from the right most character for easy of use with streams. How might you do that?

Создан 18 апр. 11 2011-04-18 23:54:26 dmckee

A char * , strictly speaking, is a pointer to a char . A pointer is just an address to some place in memory. In C/C++ (and Java), strings are made up of characters that can, individually, be treated as integers (usually one byte), thanks to ASCII.

In C (and C++), a pointer to an item of some type is the same as a pointer to an array of elements of that type. Strings in pure C are just arrays of char s, with a ‘’ (NUL) at the end so that you know when you’ve hit the end of a string without having to pass around its length everywhere (a pointer is only an address, it knows nothing about what it points to).

Ignore the const keywords for now.

The C version of atoi loops through each character in the string. The *str++ does several things (it’s important to understand how it works, but it’s a horrible way to actually write C). It’s equivalent to *(str++) . The str++ returns the value of str (a pointer) and then increments it by one (but it returns the old value!). The * «dereferences» the pointer, basically reading in a char from memory. This char is stored in digit and then compared to NUL . Characters are stored in ASCII, which represents digits contiguously, so we can just check that digit is between 0 and 9. We know now that we’re reading in a new digit, so we multiply the previous value by 10 to «shift» the value over and then add in the digit.

A C++ string is an object to make dealing with strings easier. You can get a char * from a C++ string with .c_str() .

C++ version (more likely an inlined call to the char* version with «return atoi(str.c_str());»):

Edit: Fixed issue where <> would not display properly.

Edit: C++ string version added

Edit: Fixed so it returns 123 in 123a case.

Edit: Changed stray num to n in C++ version

Создан 18 апр. 11 2011-04-18 23:57:33 Hoa Long Tam

I think this is the closest to what I’m thinking. but it’s a conversion between a string and an int not a char to an int. also. I’m just learning so if you could explain what char* and *str means. that would be appreciated greatly. (I’m pretty sure I’ve heard they’re «pointers»? but I don’t understand what they do. ) – JacKeown 19 апр. 11 2011-04-19 00:17:27

Either of your versions will return 0 for a string like «123a», whereas atoi (I believe) would return 123. Nice detail in the description though. +1 – Graeme Perrow 19 апр. 11 2011-04-19 13:00:07

@Graeme: My understanding was that it would return zero if the string was not all digits based [on this](http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/). However, this version also doesn’t handle signs and doesn’t max/min out. – Hoa Long Tam 19 апр. 11 2011-04-19 18:32:36

On that page, we have this comment: «The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function.» If I run the example on that page and enter «1234asdf» I get «The value entered is 1234.» – Graeme Perrow 19 апр. 11 2011-04-19 19:12:05

@Graeme: Ah, yes it does. I only saw the «If no valid conversion could be performed, a zero value is returned.» line. – Hoa Long Tam 19 апр. 11 2011-04-19 20:57:35

Технология программирования на Си: представление матриц, работа с файлами и с текстами

Работа с файлами

Стандартная библиотека Си содержит набор функций для работы с файлами. Эти функции описаны в стандарте ANSI . Отметим, что файловый ввод-вывод не является частью языка Си , и ANSI -функции — не единственное средство ввода-вывода. Так, в операционной системе Unix более популярен другой набор функций ввода-вывода, который можно использовать не только для работы с файлами, но и для обмена по сети. В C++ часто используются библиотеки классов для ввода-вывода. Тем не менее, функции ANSI -библиотеки поддерживаются всеми Си -компиляторами, и потому программы, применяющие их, легко переносятся с одной платформы на другую. Прототипы функций ввода-вывода и используемые для этого типы данных описаны в стандартном заголовочном файле «stdio.h.

Открытие файла: функция fopen

Для доступа к файлу применяется тип данных FILE . Это структурный тип, имя которого задано с помощью оператора typedef в стандартном заголовочном файле «stdio.h». Программисту не нужно знать, как устроена структура типа файл: ее устройство может быть системно зависимым, поэтому в целях переносимости программ обращаться явно к полям струтуры FILE запрещено. Тип данных «указатель на структуру FILE используется в программах как черный ящик: функция открытия файла возвращает этот указатель в случае успеха, и в дальнейшем все файловые функции применяют его для доступа к файлу.

Прототип функции открытия файла выглядит следующим образом:

Здесь path — путь к файлу (например, имя файла или абсолютный путь к файлу), mode — режим открытия файла. Строка mode может содержать несколько букв. Буква » r » (от слова read) означает, что файл открывается для чтения (файл должен существовать). Буква » w » (от слова write) означает запись в файл, при этом старое содержимое файла теряется, а в случае отсутствия файла он создается. Буква » a » (от слова append) означает запись в конец существующего файла или создание нового файла, если файл не существует.

В некоторых операционных системах имеются различия в работе с текстовыми и бинарными файлами (к таким системам относятся MS DOS и MS Windows; в системе Unix различий между текстовыми и бинарными файлами нет). В таких системах при открытии бинарного файла к строке mode следует добавлять букву » b » (от слова binary), а при открытии текстового файла — букву » t » (от слова text). Кроме того, при открытии можно разрешить выполнять как операции чтения, так и записи; для этого используется символ + (плюс). Порядок букв в строке mode следующий: сначала идет одна из букв » r «, » w «, » a «, затем в произвольном порядке могут идти символы » b «, » t «, » + «. Буквы » b » и » t » можно использовать, даже если в операционной системе нет различий между бинарными и текстовыми файлами, в этом случае они просто игнорируются.

Значения символов в строке mode сведены в следующую таблицу:

Несколько примеров открытия файлов:

Обратите внимание, что во втором случае мы используем обычную косую черту / для разделения директорий, хотя в системах MS DOS и MS Windows для этого принято использовать обратную косую черту . Дело в том, что в операционной системе Unix и в языке Си, который является для нее родным, символ используется в качестве экранирующего символа, т.е. для защиты следующего за ним символа от интерпретации как специального. Поэтому во всех строковых константах Си обратную косую черту надо повторять дважды, как это и сделано в третьем примере. Впрочем, стандартная библиотека Си позволяет в именах файлов использовать нормальную косую черту вместо обратной; эта возможность была использована во втором примере.

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

Константа NULL

В приведенном выше примере при открытии файла функция fopen в случае ошибки возвращает нулевой указатель на структуру FILE . Чтобы проверить, произошла ли ошибка, следует сравнить возвращенное значение с нулевым указателем. Для наглядности стандартный заголовочный файл «stdio.h» определяет символическую константу NULL как нулевой указатель на тип void :

Читать еще:  Как исправить ошибку в эксель знач

Сделано это вроде бы с благой целью: чтобы отличить число ноль от нулевого указателя. При этом язык Си, в котором контроль ошибок осуществляется недостаточно строго, позволяет сравнивать указатель общего типа void * с любым другим указателем. Между тем,в Си вместо константы NULL всегда можно использовать просто 0 , и вряд ли от этого программа становится менее понятной. Более строгий язык C++ запрещает сравнение разных указателей, поэтому в случае C++ стандартный заголовочный файл определяет константу NULL как обычный ноль:

Автор языка C++ Б. Страуструп советует использовать обычный ноль 0 вместо символического обозначения NULL . Тем не менее, по традиции большинство программистов любят константу NULL .

Константа NULL не является частью языка Си или C++, и без подключения одного из стандартных заголовочных файлов, в котором она определяется, использовать ее нельзя. (По этой причине авторы языка Java добавили в язык ключевое слово null , записываемое строчными буквами.) Так что в случае Си или C++ безопаснее следовать совету Б. Страуструпа и использовать обычный ноль 0 вместо символической константы NULL .

Диагностика ошибок: функция perror

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

Функция perror печатает сначала пользовательское сообщение об ошибке, затем после двоеточия системное сообщение. Например, при выполнении приведенного фрагмента в случае ошибки из-за отсутствия файла будет напечатано

Функции бинарного чтения и записи fread и fwrite

После того как файл открыт, можно читать информацию из файла или записывать информацию в файл. Рассмотрим сначала функции бинарного чтения и записи fread и fwrite . Они называются бинарными потому, что не выполняют никакого преобразования информации при вводе или выводе (с одним небольшим исключением при работе с текстовыми файлами, которое будет рассмотрено ниже): информация хранится в файле как последовательность байтов ровно в том виде, в котором она хранится в памяти компьютера.

Функция чтения fread имеет следующий прототип:

Здесь size_t определен как беззнаковый целый тип в системных заголовочных файлах. Функция пытается прочесть numElems элементов из файла, который задается указателем f на структуру FILE , размер каждого элемента равен elemSize . Функция возвращает реальное число прочитанных элементов, которое может быть меньше, чем numElems , в случае конца файла или ошибки чтения. Указатель f должен быть возвращен функцией fopen в результате успешного открытия файла. Пример использования функции fread :

В этом примере файл » tmp.dat » открывается на чтение как бинарный, из него читается 100 вещественных чисел размером 8 байт каждое. Функция fread возвращает реальное количество прочитанных чисел, которое меньше или равно, чем 100.

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

Внимание! Открытие файла как текстового с помощью функции fopen , например,

вовсе не означает, что числа при вводе с помощью функции fopen будут преобразовываться из текстовой формы в бинарную! Из этого следует только то, что в операционных системах, в которых строки текстовых файлов разделяются парами символами » rn » (они имеют названия CR и LF — возврат каретки и продергивание бумаги, Carriage Return и Line Feed ), при вводе такие пары символов заменяются на один символ » n » (продергивание бумаги). Обратно, при выводе символ » n » заменяется на пару » rn «. Такими операционными системами являются MS DOS и MS Windows. В системе Unix строки разделяются одним символом » n » (отсюда проистекает обозначение » n «, которое расшифровывается как new line). Таким образом, внутреннее представление текста всегда соответствует системе Unix, а внешнее — реально используемой операционной системе. Отметим также, что создатели операционной системы компьютеров Apple Macintosh выбрали, чтобы жизнь не казалась скучной, третий, отличный от двух предыдущих, вариант: текстовые строки разделяются одним символом » r » возврат каретки!

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

Функция бинарной записи в файл fwrite аналогична функции чтения fread . Она имеет следующий прототип:

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

Закрытие файла: функция fclose

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

Для закрытия файла используется функция fclose с прототипом

В случае успеха функция fclose возвращает ноль, при ошибке — отрицательное значение (точнее, константу конец файла EOF, определенную в системных заголовочных файлах как минус единица). При ошибке можно воспользоваться функцией perror , чтобы напечатать причину ошибки. Отметим, что ошибка при закрытии файла — явление очень редкое (чего не скажешь в отношении открытия файла), так что анализировать значение, возвращаемое функцией fclose , в общем-то, не обязательно. Пример использования функции fclose :

Пример: подсчет числа символов и строк в текстовом файле

В качестве содержательного примера использования рассмотренных выше функций файлового ввода приведем программу, которая подсчитывает число символов и строк в текстовом файле. Программа сначала вводит имя файла с клавиатуры. Для этого используется функция scanf ввода по формату из входного потока, для ввода строки применяется формат » %s . Затем файл открывается на чтение как бинарный (это означает, что при чтении не будет происходить никакого преобразования разделителей строк). Используя в цикле функцию чтения fread , мы считываем содержимое файла порциями по 512 байтов, каждый раз увеличивая суммарное число прочитанных символов. После чтения очередной порции сканируется массив прочитанных символов и подсчитывается число символов » n » продергивания бумаги, которые записаны в концах строк текстовых файлов как в системе Unix, так и в MS DOS или MS Windows. В конце закрывается файл и печатается результат.

Пример выполнения программы: она применяется к собственному тексту, записанному в файле «wc.cpp.

Форматный ввод-вывод: функции fscanf и fprintf

В отличие от функции бинарного ввода fread , которая вводит байты из файла без всякого преобразования непосредственно в память компьютера, функция форматного ввода fscanf предназначена для ввода информации с преобразованием ее из текстового представления в бинарное. Пусть информация записана в текстовом файле в привычном для человека виде (т.е. так, что ее можно прочитать или ввести в файл, используя текстовый редактор). Функция fscanf читает информацию из текстового файла и преобразует ее во внутреннее представление данных в памяти компьютера. Информация о количестве читаемых элементов, их типах и особенностях представления задается с помощью формата. В случае функции ввода формат — это строка, содержащая описания одного или нескольких вводимых элементов. Форматы, используемые функцией fscanf , аналогичны применяемым функцией scanf , они уже неоднократно рассматривались (см. раздел 3.5.4). Каждый элемент формата начинается с символа процента » % «. Наиболее часто используемые при вводе форматы приведены в таблице:

Ссылка на основную публикацию
ВсеИнструменты 220 Вольт
Adblock
detector