The Code needs to write some values in a file by going to the specific adresses with seekp. But when i start it only the first Array is written into the file.
The new adresses can be read from the INI like the new values but its just not going to be written in the file. Its for a games save file.
Code:
const int noq = 5;
const int noqd = 4;
int questData[noqd] = {10, 10, 10, 10};
int adresslist[noqd] ={0x0,0x0,0x0, 0x0};
fstream aus("quest1", ios::binary | ios::out | ios::in);
char buffer[512];
int i;
int j;
int Money, Prize, HRpoints, Map;
int Mappointer, Moneypointer, PrizePointer, HRpointer;
for (j=0; j <= noq; j++)
{
sprintf_s(buffer,"%d",j);
Money = GetPrivateProfileInt(buffer,"RewardMoney", 0, ".\\Settings.ini");
Prize = GetPrivateProfileInt(buffer,"Questprize", 0 , ".\\Settings.ini");
HRpoints = GetPrivateProfileInt(buffer,"RewardHRpoints", 0 , ".\\Settings.ini");
Map = GetPrivateProfileInt(buffer,"Map", 1 , ".\\Settings.ini");
questData[0] = Money;
questData[1] = HRpoints;
questData[2] = Prize;
questData[3] = Map;
Moneypointer = GetPrivateProfileInt(buffer,"RewardMoney", 0, ".\\Pointers.ini");
PrizePointer = GetPrivateProfileInt(buffer,"Questprize", 0 , ".\\Pointers.ini");
HRpointer = GetPrivateProfileInt(buffer,"RewardHRpoints", 0 , ".\\Pointers.ini");
Mappointer = GetPrivateProfileInt(buffer,"Map", 1 , ".\\Pointers.ini");
adresslist[0] = Moneypointer;
adresslist[1] = HRpointer;
adresslist[2] = PrizePointer;
adresslist[3] = Mappointer;
for (i=0; i<=noqd; i++)
{
printf("\n<Adress>\n");
aus.seekp(0x0);
aus.seekp(adresslist[i], ios::beg);
printf("\n<Write>");
aus.write(reinterpret_cast<char*>(&questData[i]), sizeof(questData[i]));
Beep(1000,100);
}
i = 0;
}
aus.close();
}
Your for loops are wrong.
for (i=0; i<=noqd; i++)
This goes 0,1,2,3,4. but your array only goes from 0 to 3.
Related
i'm trying to turn a 1d array of strings into a 2d array of chars using:
'''''''''''''''
variables
'''''''''''''''
const int width = 20;
const int height = 20;
char arena[width][height];
string arenaline[height];
'''''''''''''''
setup
'''''''''''''''
arenaline[1] = "####################";
arenaline[2] = "#..................#";
arenaline[3] = "#..................#";
arenaline[4] = "###...###..###...###";
arenaline[5] = "#.......#..#.......#";
arenaline[6] = "###...###..###...###";
arenaline[7] = "#..................#";
arenaline[8] = "###...###..###...###";
arenaline[9] = "#.......#..#.......#";
arenaline[10] = "#########..#########";
arenaline[11] = "###..............###";
arenaline[12] = "###.#####..#####.###";
arenaline[13] = "###.####....####.###";
arenaline[14] = "###.####....####.###";
arenaline[15] = "#.....###..###.....#";
arenaline[16] = "#.....###..###.....#";
arenaline[17] = "#..#..###..###..#..#";
arenaline[18] = "#.....###..###.....#";
arenaline[19] = "#.....###..###.....#";
arenaline[20] = "####################";
'''''''''''''''
conversion
'''''''''''''''
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
arena[j][i] = arenaline[i].substr(j,1);
}
}
I want it to convert from the substring to a char so I can use it in an array.
I can't use a string instead of chars because it breaks the function where the array is output to the console.
substr returns a string. string is not implicitly converted to char for "single character" strings.
The correct way to adress single characters of strings is string::operator[] or string::at().
Hello I am trying to write 8 bits from std::vector to binary file and read them back . Writing works fine , have checked with binary editor and all values are correct , but once I try to read I got bad data .
Data that i am writing :
11000111 //bits
Data that i got from reading:
11111111 //bits
Read function :
std::vector<bool> Read()
{
std::vector<bool> map;
std::ifstream fin("test.bin", std::ios::binary);
int size = 8 / 8.0f;
char * buffer = new char[size];
fin.read(buffer, size);
fin.close();
for (int i = 0; i < size; i++)
{
for (int id = 0; id < 8; id++)
{
map.emplace_back(buffer[i] << id);
}
}
delete[] buffer;
return map;
}
Write function(just so you guys know more whats going on)
void Write(std::vector<bool>& map)
{
std::ofstream fout("test.bin", std::ios::binary);
char byte = 0;
int byte_index = 0;
for (size_t i = 0; i < map.size(); i++)
{
if (map[i])
{
byte |= (1 << byte_index);
}
byte_index++;
if (byte_index > 7)
{
byte_index = 0;
fout.write(&byte, sizeof(byte));
}
}
fout.close();
}
Your code spreads out one byte (the value of buffer[i], where i is always 0) over 8 bools. Since you only read one byte, which happens to be non-zero, you now end up with 8 trues (since any non-zero integer converts to true).
Instead of spreading one value out, you probably want to split one value into its constituent bits:
for (int id = 0; id < 8; id++)
{
map.emplace_back((static_cast<unsigned char>(buffer[i]) & (1U << id)) >> id);
}
I am trying to copy a 2d character array into another 2d character array using the string function strcpy but it's giving me the error of access violation. I don't know what is it that I am doing wrong. I am posting the code and error can somebody tell me what is it that I am doing wrong
int searching(char *name[],char * namesearched,int size)
{
int count =0;
int start = 0;
int end = count;
for(;start<=end;)
{
int mid = (start + end)/2;
if(strcmp(namesearched,name[mid])==0)
{
return mid;
}
else if(strcmp(namesearched,name[mid])==1)
{
end=mid -1;
}
else if(strcmp(namesearched,name[mid])==-1)
{
start = mid +1;
}
}
return -1;
}
void sorting(char **name,char ** meaning,int count)
{
for (int i=0;i<count;i++)
{
for(int j=i+1; j<count; j++)
{
char tempname[100];
char tempmeaning[100];
if(strcmp(name[j-1],name[j])>0)
{
strcpy(tempname,name[j]);
//strcpy(name[j],tempname);
strcpy(name[j-1],name[j]);
strcpy(name[j],name[j-1]);
strcpy(name[j-1],tempname);
strcpy(tempmeaning,meaning[j]);
strcpy(meaning[j],meaning[j-1]);
strcpy(meaning[j-1], tempmeaning);
}
}
}
}
void main()
{
int size=60;
int count=0;
char namesearched[100];
cout << "Enter the name to be searched: ";
cin.getline(namesearched , 100);
char** name= new char * [size];
char** meaning = new char * [size];
for(int i=0;i < size ; i++)
{
name[i]= new char [100];
meaning[i]= new char[100];
count ++;
}
name[0] = "Journalist";
name[1] = "Blister";
name[2] = "List";
name[3] = "Listen";
name[4] = "Novelist";
name[5] = "Song";
name[6] = "Eat";
name[7] = "West";
name[8] = "Idealist";
name[9] = "Industry";
name[10] = "Legalist";
name[11] = "Write";
name[12] = "Medal";
name[13] = "Nation";
name[14] = "Accident";
name[15] = "Nest";
name[16] = "Bird";
name[17] = "Animal";
name[18] = "Lion";//wrong
name[19] = "Pigeon";
name[20] = "Real";
name[21] = "Accept";
name[22] = "Ability";
name[23] = "Bald";
name[24] = "Backbite";
name[25] = "Wakeful";
name[26] = "Absolute";
name[27] = "Wail";
name[28] = "Abiding";
name[29] = "Unacceptable";
name[30] = "Tacker";
name[31] = "Vain";//wrong
name[32] = "Abolish";
name[33] = "Taking";
name[34] = "Unarmed";
name[35] = "Habit";
name[36] = "Notus";
name[37] = "Impecle";
name[38] = "Accelerate";
name[39] = "Agony";
name[40] = "Sulk";
name[41] = "Nowise";
name[42] = "Hypocrisy";
name[43] = "Nape";
name[44] = "Eccentric";
name[45] = "Naturally";
name[46] = "Gratitude";
name[47] = "Mesmerizing";
name[48] = "Epic";
name[49] = "Abstain";
name[50] = "Enactment";
name[51] = "Hammock";
name[52] = "Nodal";
name[53] = "Laborious";
name[54] = "Nonverbal";
name[55] = "Haggle";
name[56] = "Notorious";
name[57] = "Lagger";
name[58] = "Pathetic";
name[59] = "Norms";
meaning[0] = "Sahaafi";
meaning[1] = "Chaala";
meaning[2] = "Fehrist";
meaning[3] = "Sunna";
meaning[4] = "Naval Nigaar";
meaning[5] = "Ganna";
meaning[6] = "Khanna";
meaning[7] = "Maghrib";
meaning[8] = "Tadawuri";
meaning[9] = "Sannat";
meaning[10] = "Zabta Parast";
meaning[11] = "Likhna";
meaning[12] = "Tangha";
meaning[13] = "Qoom";
meaning[14] = "Hadsa";
meaning[15] = "Ghonsla";
meaning[16] = "Parinda";
meaning[17] = "Janwar";
meaning[18] = "Shair";
meaning[19] = "Kabootar";
meaning[20] = "Haqeekat";
meaning[21] = "Qabool";
meaning[22] = "Kabliyat";
meaning[23] = "Ganja";
meaning[24] = "Ghebat Karna";
meaning[25] = "Jagta";
meaning[26] = "Bikul";
meaning[27] = "Gham Karna";
meaning[28] = "Mustakil";
meaning[29] = "NaGawar";
meaning[30] = "Jorna Wala";
meaning[31] = "Gari";
meaning[32] = "Rad kar dena";
meaning[33] = "Dil-chasp";
meaning[34] = "Nehatta";
meaning[35] = "Addat";
meaning[36] = "Dakni hawwa";
meaning[37] = "Rokna";
meaning[38] = "Taiz karna";
meaning[39] = "Sakht Takleef";
meaning[40] = "Roth Jana";
meaning[41] = "Hargiz Nahi";
meaning[42] = "Naffaq";
meaning[43] = "Mankaa";
meaning[44] = "Sanki";
meaning[45] = "Fitratan";
meaning[46] = "Tashakur";
meaning[47] = "Mashoor Karna";
meaning[48] = "Razmiya";
meaning[49] = "Baaz Rakhna";
meaning[50] = "Nifaaz";
meaning[51] = "Jholay ki tarhan ka Bichona";
meaning[52] = "Gutheela";
meaning[53] = "Mehnat Talab";
meaning[54] = "Ghair Lafzey";
meaning[55] = "Takrar Karna";
meaning[56] = "Badnam";
meaning[57] = "Ahista Chalnay walla";
meaning[58] = "Intehai afsoos naak baat";
meaning[59] = "Mayar";
int mid;
sorting( name , meaning , count);
int mid = searching(name,namesearched,count);
if( mid == -1 )
{
char ** tempname = new char* [60];
char ** tempmeaning = new char*[60];
if(count == size)
{
int increase =(10 * size)/100;
size = increase + size;
for(int i=0 ; i<size ; i++)
{
tempname[i] = new char [100];
tempmeaning[i]= new char [100];
}
for(int i = 0; i<count ; i++)
{
strcpy(tempname[i],name[i]);
strcpy(tempmeaning[i],meaning[i]);
}
}
strcpy(tempname[count] , namesearched);
cin >> tempmeaning[count];
count ++;
sorting( tempname , tempmeaning , count);
for (int i =0;i < count ;i++)
{
delete [] name[i];
delete [] meaning[i];
}
//delete [] name;
//delete [] meaning;
name = tempmeaning;
meaning = tempmeaning;
tempmeaning = NULL ;
tempname = NULL;
}
else
{
cout <<"The meaning of " << namesearched << " is: " << meaning[mid] << endl;
}
_getch();
}
Access violation writing location 0x001fbe5c.
The value of count and size is 60
One thing more strcpy works on this line strcpy(tempname , name[j]) but when it encounter this line strcpy(name[j] , name[j-1]) it throws me the error of access violation
This function declaration
void sorting(char *name[],char *meaning[],int size,int count);
does not deal with two-dimensional arrays.
For example if you have two-dimensional arrays like this
char name[60][100];
char meaning[60][100];
then the function declaration will look like
void sorting( char name[60][100], char meaning[60][100], size_t count );
or
void sorting( char name[][100], char meaning[][100], size_t count );
or
void sorting( char ( *name )[100], char ( *meaning )[100], size_t count );
and the value of the argument for the third parameter should be equal to 60.
As for your function declaration then for example this parameter char *name[]
has type of incomplete one-dimensional array of pointers of type char * that is adjusted to type char **. And if the corresponding argument is an array of pointers to string literals then the function has undefined behavior because you may not change string literals.
So it seems you are processing the arrays incorrectly that is their definitions do not correspond to the logic of the function code.
Also parameter size is not used in the function.
Thus your code simply wrong initially.
Take into account that the condition in this if statement
if(strcmp(name[j-1],name[j]))
should look either like
if ( strcmp( name[j-1], name[j] ) > 0 )
if you want to sort the arrays in the ascending order or like
if ( strcmp( name[j-1], name[j] ) < 0 )
if you want to sort the arrays in the descending order.
EDIT: After you appended your question then it is seen that 1) there are memory leaks because the pointers that initially pointed to the allocated memory are reassigned with addresses of string literals and 2) you are trying to change string literals that are immutable.
Instead of for example
name[0] = "Journalist";
you have to write
strcpy( name[0], "Journalist" );
You don't need 2d char arrays, just array of strings. So you can do it without using strcpy. Something like:
void sorting(char *name[],char *meaning[], int count)
{
for (int i = 0; i < count; i++)
{
for(int j = 1; j < count - i; j++)
{
char *tempname;
char *tempmeaning;
if(strcmp(name[j-1],name[j]) > 0)
{
tempname = name[j];
name[j] = name[j-1];
name[j-1] = tempname;
tempmeaning = meaning[j];
meaning[j] = meaning[j-1];
meaning[j-1] = tempmeaning;
}
}
}
}
char *name[] is an array of pointers to char. Pointer to char can be interpreted like a pointer to the first element of array of chars (to string). So if you want to swap two strings in array, you just need to swap pointers to that strings.
I created functions to read bit data from arbitrary bit position of char array to long long int, and I also created function to write data to char array from vector bool.
However, I do not really like my implementation since I think it has burden implementations in order to read and write bits.
Can anyone see my implementation and enlighten me for better implementation?
Here is my implementation to write bit data from vector<bool> bitdataForModification
unsigned char*& str is original char array
int startBitLocation is arbitrary bit position to read from
int sizeToModify is the size in bits for modification
void setBitDataToBitPosition(unsigned char*& str, int startBitLocation, int sizeToModify, std::vector<bool>& bitdataForModification){
int endBitLocation = startBitLocation + sizeToModify-1;
int sizeChar = (endBitLocation - startBitLocation)/8;
//Save leftover data
int startCharPosition = startBitLocation/8;
int startLeftOverBits = startBitLocation%8;
//endPosition
int endCharPosition = endBitLocation/8;
int endLeftOverBits = 7-(endBitLocation%8);
unsigned char tempChar = str[startCharPosition];
unsigned char tempLastChar = str[endCharPosition]; // store last char
int posBitdata = 0;
for(int i = 0 ; i < startLeftOverBits; i++){
str[startCharPosition] <<= 1;
str[startCharPosition] = (str[startCharPosition] | ((tempChar >> (7-i)) & 0x1));
}
for(int i = startCharPosition*8 + startLeftOverBits ; i <= endBitLocation ; i++){
str[i/8] <<= 1;
if(posBitdata <= endBitLocation){
str[i/8] = (str[i/8] | ((bitdataForModification[posBitdata]) & 0x1));
posBitdata++;
}
}
for(int i = 0 ; i < endLeftOverBits ; i++){
str[endCharPosition] <<= 1;
str[endCharPosition] = (str[endCharPosition] | ((tempChar >> i) & 0x1));
}
}
I do not like above function because it copies from original char[] to temp char[] and copy back the bits I need.
Following is my read function I implemented.
It reads from char array and copy the data to long long int data
void getBitDataFromBitPosition(unsigned char* str, int startBitLocation, int sizeToRead, unsigned long long* data){
int endBitLocation = startBitLocation + sizeToRead;
int sizeChar = (endBitLocation - startBitLocation)/8;
int startCharPosition = startBitLocation/8;
int endCharPosition = endBitLocation/8 +1;
vector<bool> bitData;
int bitCnt = 0;
for(int i = startCharPosition; i < endCharPosition; i++){
unsigned char tempChar = str[i];
for(int j = 7 ; j >= 0 ; j--){
int curLoc = ((i*8)+(bitCnt%8));
if(curLoc >= startBitLocation){
if(curLoc < endBitLocation){
bool temp = ((str[i] >> j) & 0x1);
bitData.push_back(temp);
}
}
bitCnt++;
}
}
for(int i = bitData.size() -1 ; i >= 0 ; i--){
*data <<= 1;
*data = (*data | bitData[bitData.size()-i-1]);
}
}
I think it is burden to copy to bool vector and copy back to long long int.
Can anyone provide better solution for me?
Thank you in advance!
I have an API function that takes constant char * as an input. I have to create a delimited text file which is the input of the function like:
193.875 0.0 0.0 2
193.876 0.0 0.0 2
193.877 0.0 0.0 2
193.878 0.0 0.0 2
193.879 0.0 0.0 2
193.880 0.0 0.0 2
193.881 0.0 0.0 2
the support guy of the software told me that I can create and save every line of this file by using sprintf() so I used it like:
sprintf(wsp,"%.3f\t0.0\t0.0\t%d\n", start_freq, z);
and after putting this line in loop I saved every created wsp in an array of string:
for (int j = 0; j < start; j++){
sprintf(wsp,"%.3f\t0.0\t0.0\t%d\n", start_freq, z);
start_freq = start_freq + 0.001;
wspfile[j] = wsp;
}
now I have a file with the required format but comes in array of string. My question is after creating the array how can I pass this array as a constant char * or how can I convert it to constant char *
You could make wspFile an std::string instead of an array. Then instead of
wspFile[j]=wsp;
you would have
wspFile+=wsp;
Then to get the const char* version you would call
wspFile.c_str();
I hope I have not misunderstood your question. I start assuming I have an array of N char*, namely wspfile[], right? Now, I want to convert this array to a single string:
char *join(char **strings, int N)
{
//Step 1: find out the total amount of memory we need
int i, total = 0;
for (i = 0; i < N; i++) {
total += strlen(strings[i]);
}
//Step 2. Allocate resulting string.
char *str = malloc(total + 1); //Alloc 1 more byte for end \0
//Step 3. Join strings.
char *dst = str;
for (i = 0; i < N; i++) {
char *src = strings[i];
while(*src) *dst++ = *src++;
}
*dst = 0; //end \0
return str; //don't forget to free(str) !
}
Then, in your code:
char *s = join(wspfile, N);
/* do whatever with `s`*/
free(s);
It seems that you know the size of your data upfront, so you could do it like this:
std::vector<char> wspfile(start * wsp_max_length);
// C-ish way:
/* char* wspfile = (char*) malloc(start * wsp_max_length) */
for (int j = 0; j < start; j++) {
sprintf(wsp + (wsp_max_length * j), "%.3f\t0.0\t0.0\t%d\n", start_freq, z);
start_freq = start_freq + 0.001;
}
your_API_func(&wspfile[0]);
In more C++ like fashion:
#include <vector>
#include <sstream>
#include <string>
#include <iomanip> // for setprecision()
std::vector<char> wspfile;
double start_freq = 193.875;
for (int j = 0; j < start; ++j, start_freq += 0.0001) {
std::ostringstream oss;
oss << std::setprecision(3)
<< start_freq
<< "\t0.0\t0.0\t"
<< z << "\n\0"; // your version with sprintf adds '\0', too,
// although I'm pretty sure you don't want it
std::string wsp = oss.str();
wspfile.insert(wspfile.end(), wsp.begin(), wsp.end());
}
your_API_func(&wspfile[0]);