Я пытаюсь прочитать матрицу целых чисел из файла, используя 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
Значение 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. Файл не будет читаемым человеком, но он будет выполнять ваши задачи.
Читая это как 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
это лучшее решение ..