I'm trying to read comma separated data from a line from a .txt file and then parse the data into 2 different arrays (names & indScores). From the indScores[], I'm getting the overall average for a particular name and storing that into my avg_scores[]. Then at the very end, return total lines that were read.
Sample input data looks like this:
name1,x1,x2,x3,x4,x5
name2,y1,y2,y3,y4,y5
name3,z1,z2,z3,z4,z5
name4,a1,a2,a3,a4,a5
....
My arrays output this
names[name2, name4, name6, name8,...]
avg_scores[x_avg, x_avg + y_avg, x_avg + y_avg + z_avg,...]
And my overall line count is half of what I'm expecting. Am I indexing at the wrong position or is my logic wrong?
int ReadScores(string fileName, string names[], float avg_scores[], int array_size){
float indScores[array_size];
int lineCounter = 0;
string myLine, nameSubString, scoreSubString;
float scoreConvert = 0.0;
float averageScores = 0.0;
ifstream myFileIn;
//open the file
myFileIn.open(fileName, ios::in);
if (myFileIn.fail()){
cout << "Error opening "<< fileName << endl;
return 0;
}
int index = 0;
//read the file with a while loop until the end of file is reached
while (getline(myFileIn, myLine)){
averageScores;
getline(myFileIn, myLine);
//firstComma will hold the integer value of the index position of the first comma found
int firstComma = myLine.find(',');
//this should grab the the names at the beginning of each string on each new line
nameSubString = myLine.substr(0, firstComma);
names[index] = nameSubString;
int startingPos = 0;
float commaCounter = 0;
//find how many commas are in a string and use that to limit your loop
for (int ind = 0; ind < myLine.length(); ind++){
if (myLine[ind] == ',')
commaCounter++;
}
for (int ind = 0; ind < commaCounter; ind++){
//grab the first number and store it the scoreSubString variable
//this tells the myLine.substr to start after the very first comma
int found = myLine.find(',', firstComma) + 1;
scoreSubString = myLine.substr(found, myLine.find(','));
//change the value of firstComma to the next index location
firstComma = found + 1;
///convert string to number
stringstream(scoreSubString) >> scoreConvert;
///store number in float array
indScores[ind] = scoreConvert;
}
for (int ind = 0; ind < commaCounter; ind++){
averageScores = indScores[ind] + averageScores;
}
float averageOverall = averageScores/commaCounter;
//store the averageOverall into the avg_scores []
avg_scores[index] = averageOverall;
index++;
lineCounter++;
}
myFileIn.close();
return lineCounter;
}
Right, once I deleted that second getline(myFilenIn, myLine) things started to match up.
I also needed to reset my averageScores = 0 before the for loop that was getting my averageScores and add a starting position found for my .find(',', found), without it I was constantly starting from the beginning.
My new code looks like this:
int ReadScores(string fileName, string names[], float avg_scores[], int array_size){
int linesCounted = 0;
float indScores[array_size];
int lineCounter = 0;
string myLine, nameSubString, scoreSubString;
float scoreConvert = 0.0;
float averageScores = 0.0;
ifstream myFileIn;
//open the file
myFileIn.open(fileName, ios::in);
if (myFileIn.fail()){
cout << "Error opening "<< fileName << endl;
return 0;
}
int index = 0;
//read the file until the end of file is reached
while (getline(myFileIn, myLine)){
//firstComma will hold the integer value of the index position of the first comma found
int firstComma = myLine.find(',');
//this should grab the the names at the beginning of each string on each new line
nameSubString = myLine.substr(0, firstComma);
names[index] = nameSubString;
int startingPos = 0;
float commaCounter = 0;
//find how many commas are in a string and use that to limit your loop
for (int ind = 0; ind < myLine.length(); ind++){
if (myLine[ind] == ',')
commaCounter++;
}
for (int ind = 0; ind < commaCounter; ind++){
//grab the first number and store it the scoreSubString variable
int found = myLine.find(',', firstComma) + 1;
scoreSubString = myLine.substr(found, myLine.find(',', found));
//change the value of firstComma to the next index location
firstComma = found + 1;
///convert string to number
stringstream(scoreSubString) >> scoreConvert;
///store number in float array
indScores[ind] = scoreConvert;
}
averageScores = 0;
for (int ind = 0; ind < commaCounter; ind++){
averageScores = indScores[ind] + averageScores;
}
float averageOverall = averageScores/commaCounter;
avg_scores[index] = averageOverall;
index++;
if (!myLine.empty()){
lineCounter++;
}
}
myFileIn.close();
return lineCounter;
}
Related
I am trying to make a function that reads all the numbers from a text file into an array, where each line of the file has a number, ex:
57346
40963
24580
98307
98312
32777
10
16392
16396
...
My function does allocate the necessary size to store the values, but the values being stored are random ones and 0's that aren't in my text file. Output ex:
0
0
296386
0
-485579776
-653048057
584
0
2095946880
...
This is my code:
typedef struct set{
void** values;
int size;
}Set;
int checkSize(FILE* file) {
int counter = 0;
char chr;
chr = getc(file);
while (chr != EOF) {
if (chr == '\n') {
counter = counter + 1;
}
chr = getc(file);
}
return counter;
}
Set* readSet(FILE* file){
Set* new = malloc(sizeof(Set));
new->size = checkSize(file);
new->values = malloc(sizeof(void*)*new->size);
int arrayAux[new->size];
int i = 0, n;
while(i < new->size) {
fscanf(file, "%ld", &arrayAux[i]);
new->values[i] = arrayAux[i];
i++;
}
//loop to remove the first three lines of the file, which are the number of values in the file,
//the biggest value of the file and the division between the number of values and the biggest value
for(i = 0; i < 3; i++) {
new->values[i] = new->values[i + 1];
new->size--;
}
for (i = 0; i <= new->size; i++) {
printf("%d\n", new->values[i]);
}
return new;
}
How can I fix this? Thanks in advance for any help.
Why void and not long?
You cannot do int arrayAux[new->size]; as size is a variable and thus cannot be used at compile time !!! 100% guarantee of reading out of bounds.
Read the value from file into a long and assign it to the proper space in your list.
Why have the size in every row? Use a global int
why loop to step over the first three in the list?
size -=3
i+=3
Works just as well
I'm creating a code for encryption and decryption for Vernam Cipher.
Initially, to encrypt a message, I would have to use a function that would generate my OTP. This function produces random numbers from 1-26 (to signify the english alphabet) and would be stored in an array of integers. The size is equal to the length of the message to be encrypted.
I was able to do that. My problem is how I would decrypt it.
I have this code.
My OTP array, since each element is randomized between 1-26, would signify an nth letter of the alphabet. e.g. 25 would signify the letter 'y' and so on.
The logic of my encryption is that since the size of my OTP array is equal to the length of my message, I would do XOR on each of the character of my message and my OTP. This is after converting my OTP array to corresponding letters of the alphabet depending on each element's randomized assigned number.
I was able to do the encryption part already. But whenever I try to decrypt, I get a different message from what I initially inputted.
void encryptiondecryption(char msg[], char key[]){
int i,j=0,x,m=0;
char output[100];
char output2[100];
/* Loop to remove all spaces in the message here*/
/*Encryption*/
int modd;
for(x = 0; msg[x]!='\0'; x++) {
printf("\nletter:%c - key:%c",msg[x], key[x] );
modd = (msg[x] ^ key[x]);
if(modd == 26){
output[x] = 'a'+ (modd%26)+25;
}else{
output[x] = 'a'+ (modd%26)-1;
}
}
output[x]='\0';
printf("\nEncrypted Message:\n");
for(x = 0; output[x]!='\0'; x++) {
printf("%c",output[x]);
}
/* decryption */
int modd2,diff,sum, toXOR;
printf("\n\ndecryption\n");
for(x = 0; output[x]!='\0'; x++) {
printf("\nletter:%c - key:%c",output[x], key[x] );
diff = output[x] - 'a';
if(diff == 25){
sum = diff - 25;
toXOR = sum + 26;
output2[x] = toXOR ^ key[x];
}else{
sum = diff + 1;
toXOR = sum + 26;
output2[x] = toXOR ^ key[x];
}
}
output2[x]='\0';
printf("\n Output for Decryption\n");
for(i = 0; output2[i]!='\0'; i++) {
printf("%c",output2[i]);
}
}
In addition, this is my generateOTP function.
char* generateKey(char msg[]){
srand(time(NULL));
int len = strlen(msg);
int numbers[len];
int x,y=0, m=0,a;
for(x=0;x<len;x++){
if(msg[x]!='_') m++;
}
printf("generated key is . . .\n");
int *getOTP = malloc (sizeof (int)*len);
for(x=0;x<m;x++){
getOTP[x] = rand() % (26 - 1 + 1) + 1;
}
for(x=0;x<m;x++){
printf("%d ", getOTP[x]);
}
char *letterOTP = malloc (sizeof (char) * len);
int getOTP2[m];
for(x=0;x<m;x++){
getOTP2[x] = getOTP[x];
}
int md;
for(x=0;x<m;x++){
md = (getOTP2[x]) % 26;
if(md ==0){
letterOTP[x] =( 97 + (md));
}else{
letterOTP[x] =( 97 + (md) - 1);
}
}
letterOTP[x] = '\0';
return letterOTP;
}
Basically, what this does as I have mentioned above, is that assigns a letter of an alphabet depending on what number an element in the array was randomly assigned to (e.g. 25 = 'y', 5 = 'e')
I was trying to print some array but it won't print no matter what.
Which part did I do wrong?
Is it the array?
int main()
{
int i;
char id[3]; ///sample data wanted to print
id[0] = 'id1';
id[1] = 'id2';
id[2] = 'id3';
for (i = 1; i <= 3; ++i)
{
printf("%s", id[i]); ///The error appeared here////
}
}
i starts at 1, and goes to 3:
for (i = 1; i <= 3; ++i)
But you set up your array so that valid indicies are 0, 1, and 2.
3 is not a valid index.
Convention C-loops always look like this:
for(i = 0; i < 3; ++i)
That is, they start at 0 and go while less than the size of the array.
Not less than or equal to. That is your mistake.
Next, each element of the array is a single character.
But you are trying to initialize them with 3-letters, such as: id1.
A single character can hold ONE LETTER ONLY, not a set of 3 letters.
You are trying to print them out using %s; but %s is for strings, not single characters.
Here is a corrected version of your program.
int main()
{
int i;
char* id[3]; // Declare strings, not characters.
id[0] = "id1"; // Initialize each with a string
id[1] = "id2";
id[2] = "id3";
for (i = 0; i < 3; ++i) // Set loop limit correctly.
{
printf("%s\n", id[i]);
}
}
You invoked undefined behavior by passing data having wrong type: %s expects an pointer to a null-terminated string while you passed id[i], whose type is char (expanded to int here).
You can use %c to display the values of implementation-defined values of multi-character character literals.
Also The loop range is wrong as #abelenky says.
#include <stdio.h>
int main()
{
int i;
char id[3]; ///sample data wanted to print
id[0] = 'id1';
id[1] = 'id2';
id[2] = 'id3';
for (i = 0; i < 3; ++i)
{
printf("%c", id[i]);
}
}
Or do you mean this?
#include <stdio.h>
int main()
{
int i;
const char* id[3]; ///sample data wanted to print
id[0] = "id1";
id[1] = "id2";
id[2] = "id3";
for (i = 0; i < 3; ++i)
{
printf("%s\n", id[i]);
}
}
I have a basic text file I point my program at to run that has numbers line by line such as:
3
30
300
3000
30000
300000
3000000
30000000
300000000
-3
-30
-300
-3000
-30000
-300000
-3000000
-30000000
-300000000
and I need to print them out into evenly spaced columns and I want them to fit into 40 characters (4 columns wide). I want to use the sprintf function to do this. So basically print each number out plus 2 spaces for formatting and fit within 40 characters total. So far this is what I have.
int main(int argc, char *argv[]){
int a, b, num[1000], nums = 0;
char str[40];
FILE *pt;
int col, max, w;
if(argc < 2){
printf("Usage %s <No Files>\n", argv[0]);
return 1;
}
if((pt = fopen(argv[1], "r")) == NULL){
printf("Unable to open %s for reading.\n", argv[1]);
return 1;
}
while(fscanf(pt, "%d", &b) == 1){
num[nums++] = b;
}
w = sprintf(str, "%*d", num[a]);
if(max < w){
col = 40 / (max + 2);
printf("%d %d\n", w, num[a]);
}
return 0;
}
I just get garbage when I point it to the text file mentioned in the above. Any advice?
To print N numbers in 4 columns with width 10 characters use printf("%10d") inside the loop that add new line (\n) after each 4th printing, e.g.:
for (int i = 1; i <= nums; i++)
{
printf("%10d", num[i-1]); // or printf("%-10d", num[i-1]);
if (i % 4 == 0)
printf("\n"); // or putchar ('\n')
}
sign - in the format %-10d change alignment.
As you see sprinf is not used here, I use printf for each number to print the value at screen (standard output).
UPDATE:
If you want to find optimal width of the column, and use it for output, e.g. using the number of digits in your biggest number (let it be maxValue an integer value found in the array num), you can find the minimum required number of digits (let it be minWidth), like:
char buff[20] = {0};
int minWidth = strlen(_itoa(maxValue,buff,10));
and then change the printing loop like:
for (int i = 1; i <= nums; i++)
{
printf("%*d", minWidth + 1, num[i - 1]);
if (i % 4 == 0) putchar('\n');
}
here vlaue minWidth + 1 will be used in format specifier %*d instead of *, and +1 is used for minimum separation between columns in one space (of course, there can be 2 or 3).
Finally, having the column width calculated, you can find the number of column for your screen and use this value for starting new line, e.g.:
const int screenWidth = 80;
int colWidth = minWidth + 2; // here 2 is added for minimum separation of columns
int colNum = screenWidth / colWidth;
for (int i = 1; i <= nums; i++)
{
printf("%*d", colWidth, num[i - 1]);
if ( !(i % colNum) ) putchar('\n'); // !(i % colNum) is the same to i % colNum == 0
}
This is my second answer for the same question, but this answer more close to the topic - here output is made to the string with sprintf.
So, lets we have array of numbers int num[1000] and we need to print nums of them to several string (length is limited by value stringMaxLength) using formatting as columns with width depending on length of number representation (maximum number in the array).
The following snippet has comments for all operations
// string that will be made from numbers
const int stringMaxLength = 120;
char str[stringMaxLength + 1]; // just one string
// find longest number considering sign
char buff[20] = { 0 };
int maxNumWidth = 0, numWidth;
int n;
for (n = 0; n < nums; n++)
{
numWidth = strlen(_itoa(num[n], buff, 10));
if (numWidth > maxNumWidth)
maxNumWidth = numWidth;
}
int colWidth = maxNumWidth + 1; // a column size with one space between columns
int colNum = stringMaxLength / colWidth; // number of columns in one string
int s, i; // i - nums counter, s - strings counter
for (i = 0, s = 1; i < nums; s++) // loop counts strings but with condition for nums
{
int sizeCnt = 0; // start making new string str
// loop works while there are numbers and the line is not filled completely
while (i < nums)
{
// add next number (column) to the string and increase string size
sizeCnt += sprintf(str + sizeCnt, "%*d", colWidth, num[i++]);
if (i % colNum == 0) // if string has colNum numbers it is full
{
break; // stop while loop
}
}
// next string is ready and can be used
printf("%d : %s\n", s, str); // e.g. for output
}
I'm sound file that I've record using the `ALSA' lib using following setups :
Fs = 96000; // sample frequency
channelNumber = 1 ;
format =int16 ;
length = 5sec;
meaning that I get 480000 16bit value. Now I want to calculate the PSD of the set of that to get something like :
what I'm trying to do is tto save the result as a bunch of double value in a extra data so I can plot them of evaluating them ( I'm not sure if that's correct) :
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <fftw3.h>
int main(){
char fileName[] = "sound.raw";
char magnFile[] = "data.txt";
FILE* inp = NULL;
FILE* oup = NULL;
float* data = NULL;
fftwf_complex* out;
int index = 0;
fftwf_plan plan;
double var =0;
short wert = 0;
float r,i,magn;
int N = 512;
data =(float*)fftwf_malloc(sizeof(float)*N);
out = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex)*N);
//Allocating the memory for the input data
plan = fftwf_plan_dft_r2c_1d(N,data,out, FFTW_MEASURE);
// opening the file for reading
inp = fopen(fileName,"r");
oup = fopen(magnFile,"w+");
if(inp== NULL){
printf(" couldn't open the file \n ");
return -1;
}
if(oup==NULL){
printf(" couldn't open the output file \n");
}
while(!feof(inp)){
if(index < N){
fread(&wert,sizeof(short),1,inp);
//printf(" Wert %d \n",wert);
data[index] = (float)wert;
//printf(" Wert %lf \n",data[index]);
index = index +1;
}
else{
index = 0;
fftwf_execute(plan);
//printf("New Plan \n");
//printf(" Real \t imag \t Magn \t \n");
for(index = 0 ; index<N; index++){
r=out[index][0];
i =out[index][1];
magn = sqrt((r*r)+(i*i));
printf("%.10lf \t %.10lf \t %.10lf \t \n",r,i,magn);
//fwrite(&magn,sizeof(float),1,oup);
//fwrite("\n",sizeof(char),1,oup);
fprintf(oup,"%.10lf\n ", magn);
}
index = 0 ;
fseek(inp,N,SEEK_CUR);
}
}
fftwf_destroy_plan(plan);
fftwf_free(data);
fftwf_free(out);
fclose(inp);
fclose(oup);
return 0 ;
}
the problem that I have is how can I implement the winding function in my code ?
and I don't think that result is accurate, since I'get a lot of zero in magnitude values ? ?
if somebody has an example I'll be thankful .
Here is a simple example of applying a "Hanning" window to your data prior to the FFT:
for (int i = 0; i < N; ++i)
{
data[i] *= 0.5 * (1.0 + cos(2.0 * M_PI * (double)i / (double)(N - 1)));
}