mmap читает устаревший массив целых чисел из файла

Я пытаюсь прочитать матрицу целых чисел из файла, используя mmap. Если я получаю это как указатель на символ из функции mmap, я вижу все правильно, но если я использую указатель int, это дает мне устаревшие данные. Проблема с использованием указателя на символ состоит в том, что мне нужно проанализировать всю строку, используя strtok или что-то еще, и получить целые числа один за другим. Размер моей матрицы будет 4k * 4k, поэтому многие вызовы sscanf и strtok неэффективны. Пожалуйста, посмотрите на программу и вывод

#define INTS 3 * 3

int main()
{

FILE* in = fopen("int_file", "rb");
int* ints = (int*)mmap(0, INTS * sizeof(int),
PROT_READ, MAP_FILE | MAP_PRIVATE, fileno(in),0);
fclose(in);
for(int i = 0; i < INTS; ++i) {
std::cout << ints[i] << std::endl;
}
munmap(ints, INTS * sizeof(int));
return 0;
}

Содержимое int_file

510 20 30
40 50 60
100 200 10000

Выход

540029237
857747506
808716848
540030240
822751286
84097028

0

Решение

Значение ACSII текста печатается.

Ваш текст выглядит так:

510 20 30...

Из таблицы ASCII (чтобы объяснить, что я хочу сказать):

No.       ASCII (hex)

Space ->   20
0     ->   30
1     ->   31
2     ->   32
3     ->   33
5     ->   35

int является 4 байт по размеру, поэтому, беря первый 4 байт:

Преобразование в ASCII, "510 " дает "35 31 30 20" в памяти, которая 0x20303135 (540029237 как десятичное) для немного порядкового номера машины.
Точно так же, следующий 4 байтов "20 3" дает 0x33203032(857747506 как десятичное число).
Это то, что вы получаете.

В этом случае вам нужно преобразовать каждый ACSII в целое число, используя atoi () или аналогичный.

Но вы можете хранить ваши целые числа как их двоичное значение, а не как ASCII. Файл не будет читаемым человеком, но он будет выполнять ваши задачи.

2

Другие решения

Читая это как int * возможно, если данные в файле хранятся из массива int или непрерывной памяти через calloc. писатель должен выглядеть так,

#include <iostream>
#include <sys/mman.h>
#include <stdio.h>

using namespace std;

int inst[] = {510, 20, 30, 40, 50, 60, 100, 200, 10000 };

#define INTS 3 * 3

int main()
{
FILE* out = fopen("int_file", "wb");  // Error checks are needed
char *ptr = (char *) inst;
fwrite( ptr, sizeof( int ), INTS, out );
fclose( out);
return 0;
}

Тогда читатель можно читать с помощью mmap вроде как в вашем коде,

#include <iostream>
#include <sys/mman.h>
#include <stdio.h>

using namespace std;

#define INTS 3 * 3

int main()
{

FILE* in = fopen("int_file", "rb");    // Error checks are needed
int* ints = (int*)mmap(0, INTS * sizeof(int),
PROT_READ, MAP_FILE | MAP_PRIVATE, fileno(in),0);
fclose(in);
for(int i = 0; i < INTS; ++i) {
std::cout << ints[i] << std::endl;
}
munmap(ints, INTS * sizeof(int));
return 0;
}

Если не хранится из массива или непрерывной памяти, то с помощью char * а также strtok а также atoi это лучшее решение ..

0

По вопросам рекламы [email protected]