Error printing a string - c

I'm creating a algorithm that generate numbers (numbers like strings) from 0 to 9999 and search its frequency in a array a[50000].
char key[4];
int freq;
for (int i = 0; i < 10000; i++) {
sprintf(key,"%04i",i); // save 4 digits in key, if i <1000 save leading 0's
freq = BruteForceStringMatch(key,a,n); //n length of a.
printf("%s-%i\n",key,freq);
}
free(a);
but, when I run the program, I get it.
.
.
.
9845-7
9846
-10
9847-4
9848-5
-139
9850-3
9851-6
9852-5
9853-4
9854-2
9855-7
9856-5
9857-4
9858-5
9859 -9
9860-3
.
.
.
9968-6
9969 -9
9970-5
9971-4
9972-7
9973-6
9974-6
9975-2
9976-7
9977-4
9978-2
9979-7
9980-3
9981-4
9982-3
9983 -9
9984-6
9985-7
998-8
9987 -9
9988-3
9989 -9
9990-4
9991-3
9992-5
9993-2
9994 -9
9995-5
9996-6
9997-7
9998-7
There are tabs in randoms position,sometimes the last digit of key is eliminated and there are 139,113,etc that I have no idea where they come from. I'm using gcc version 5.4.0 (GCC) and compile it with windows 10 and the terminal babun.
More information:
BruteForceStringMatch search the frequency of key in a.
int BruteForceStringMatch(char key[4], char* a, int length ){
int freq=0;
int k;
for (int j = 0; j < length -4; j++) {
k =0;
while(k <4 && key[k] == a[j+k])
k=k+1;
if(k == 4)
freq++;
}
return freq;
}
I get a from a file with 5000 digits.
FILE *inputfile;
char c;
int largo = 0;
char *a = (char *)malloc(50000*sizeof(char *));;
char *b = (char *)malloc(50000*sizeof(char *));;
inputfile = fopen("archivo_1.tex", "r");
if (inputfile == NULL) {
fprintf(stderr, "Failed to open the file.\n");
exit(1);
}
if (inputfile) {
for ( int i=0; (c = getc(inputfile)) != EOF; i++){
a[i] = c;
//putchar(a[i]);
largo++;
}
fclose(inputfile);
}

It seems to me your problem is that you defined "key" to only be four chars, when it should be five -- four digits plus the terminating null. So that null ends up in the first byte of "freq"... then when you set "freq" in line 5, that value gets seen by printf (on line 6) as part of the "key" string. In particular, you can see this in the output for the values 9859 and 8859, where the value of "freq" happens to be 9, which is the ASCII code for a tab. Also, for value 9846 and "freq" is 10, which happens to be the ASCII value for linefeed (i.e., newline), and on 9849, where "freq" is 13, which is a carriage return, so "-13" prints over the first three characters of 9849.

Related

Why do "f" and "g" ASCII characters turn negative in this code?

#include <stdio.h>
/*************** CAESAR CYPHER *****************
-Take a charater array input
-Loop through 26 character shifts
-Print all possibilities
************************************************/
void Brute_Force(char *message)// Character array pointer
{
char *i;// Copy message for iteration: Stop at '/0'
int j;// Iterate through the alphabet
char t;//Temp variable for current letter
for(j = 0; j < 26; j++)
{
printf("\n----------Shift %i----------\n", j);//Aesthetics
for(i = message; *i != '\0'; i++)
{
//Multiple of 26 to start at original message
unsigned char t = ((*i + j)%26) + 104;
// Only loop 97 to 122. ASCII 'a'-'z'
if(t > 122){t = t - 26;}
printf("%c", t);
}
}
}
int main()
{
char mess[26] = "ynkooejcpdanqxeykjrbdofgkq";
Brute_Force(mess);
return 0;
}
Before changing t to an unsigned char instead of a regular char, every time 'f'(102) or 'g'(103) would come up, it would output t = -127/-128 instead of 127/128. I'm just wondering what would have caused it to change to negative. It was only for 'f' and 'g', every other letter was correct.
a sample output would be:
ynkooejcpdanqxeykjrbdo��kq

Trying to debug program

You are tasked to create a program that will read in a text file and compute statistics on the contents. Your program will count the number of alphabetic characters using isalpha(), the number of digits using isdigit() and the number of punctuation using ispunct(). (Zybook module 11). Your program will provide an appropriate report to display the analysis results to the user. Your program should work with any text file and the user should be able to select the file for input. You may create a test text file for testing and development. I suggest a short paragraph with punctuation and numbers that you can easily test the values with. Your array may be a VLA or FLA array. I suggest using an array of pointers and for each line of the text file allocate an array using calloc(). You may declare a static array, so long as it will hold 100 lines of 80 characters. A line length of 80 characters will be assumed.
Ive written most of the code but am getting a couple warnings and the program terminates abruptly and gives me a segmentation error.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(void) {
//Declarations
char paragraphArray[100][80], filename[50];
int i = 0, puncts = 0, alphas = 0, nums = 0, line = 0;
//Ask user what file to load and assign it to filename
printf("Enter the filename to wish to load: ");
scanf("%s", filename);
//FIle pointer is tagged
FILE *fPoint;
//Opens file pointer as the user-named file in read mode
fPoint = fopen(filename, "r");
//If file not found, a NULL value is assigned and prints to screen.
if(fPoint == NULL)
printf("Cannot open file");
//Else statement that reads the file line by line starting at index i=0
else
{ i=0;
while(fgets(paragraphArray[i], 80, fPoint))
{ paragraphArray[i][(strlen(paragraphArray[i]))-1]='\0';
i++;
}
//After while loop is finished, the value of i is stored as number of lines.
line = i;
}
//Closing the file
fclose(fPoint);
//Function Calls
alphas = IsAlpha(paragraphArray, i);
nums = IsDigit(paragraphArray, i);
puncts = IsPunct(paragraphArray, i);
//Display statistics to screen.
printf("There are %d alphabet characters.\n", alphas);
printf("There are %d numerical digits.\n" , nums);
printf("There are %d punctuation marks.\n" , puncts);
}
//Function Definitions
int IsAlpha(char paragraphArray[100][80], int line){
int alphaCount = 0, i = 0, j = 0, asciiValue = 0;
//Outer loop that iterates through each line of the paragraph.
for(i = 0; i < line; i++){
//Inner loop that compares elements of the array to ASCII values
for(j = 0; j < 80; j++){
asciiValue = paragraphArray[i][j];
//if statement that does the comparison and adds to count value
if((asciiValue <= 90 && asciiValue >= 65) || (asciiValue >= 97 && asciiValue <= 122))
alphaCount++;
}
}
//Returns count of alphabet characters after all iterations.
return alphaCount;
}
int IsDigit(char paragraphArray[100][80], int line){
int digitCount = 0, i = 0, j = 0, asciiValue = 0;
//Outer loop that iterates through each line of paragraph
for(i = 0; i < line; i++){
//Inner loop that compares elements of array to ASCII values.
for(j = 0; j < 80; j++){
asciiValue = paragraphArray[i][j];
//If statement that does the comparison and adds count value.
if(asciiValue >= 48 && asciiValue <= 57)
digitCount++;
}
}
//Returns count of numbers after all iterations.
return digitCount;
}
int IsPunct(char paragraphArray[100][80], int line){
int punctCount = 0, i = 0, j = 0, asciiValue = 0;
//Outer Loop that iterates through each line of paragraph.
for(i = 0; i < line; i++){
//Inner loop that compares elements of array to ASCII Values
for(j = 0; j < 80; j++){
asciiValue = paragraphArray[i][j];
//If statement that does comparison and adds count value.
if((asciiValue >= 33 && asciiValue <= 47) || (asciiValue >= 58 && asciiValue <= 64) || (asciiValue >= 91 && asciiValue <= 96) ||(asciiValue >= 123 && asciiValue <= 126))
punctCount++;
}
}
return punctCount;
}
Your problem is in for loop condition.
You itterate with the condition i < 80, but, if your line is lower than 80,
you compare undefined value.
Instead of 80 use strlen.
You can also use valgrind or gdp to debug your program. :)

Why is fwrite writing each character so many times?

I'm trying to write a program that uncompresses a file which was already compressed using run length encoding. For some reason each character is getting printed to the file many times. For example if the input file contains 1l1i1n... my output file is showing llllllllll...
I've tried printing the reps variable from the for loop to the terminal to make sure it is set to the correct number of repetitions, and even tried using fprintf but getting the same results. Im not sure what it is but there must be something here Im not understanding?
By the way, the compressed file is opened in binary mode as well from the main function.
int uncompress_file(FILE *fd_compressed, const char *fname_out)
{
FILE *fd_out;
if (fd_compressed == NULL) {
fprintf(stderr, ...);
return -1;
}
if ((fd_out = fopen(fname_out, "wb")) == NULL) {
fprintf(stderr, ...);
return -1;
}
unsigned char cur, reps;
int i = 0;
while (fread(&cur, sizeof(unsigned char), 1, fd_compressed) > 0) {
if (i % 2 == 0) {
reps = cur;
}
else {
for (int j = 0; j < reps; j++)
fwrite(&cur, sizeof(unsigned char), 1, fd_out);
}
i++;
}
fclose(fd_out);
return 0;
}
The problem is your line reps = cur. If your file is 1l1i1n then when we first enter the loop, reps will be assigned the value 1. But this is ASCII 1, not the actual number 1. A 1 in ASCII maps to the decimal 49, so you will get 49 l's. To convert the char from an ASCII number to the proper int value, you can subtract 48 from it, i.e. reps = cur - 48.
Note that this, along with your code, only works if the maximum number possible is 9 (no double-digits)

When using fprintf I get mirrored array of chars in the output

I'm converting numbers from 10 counting system (c.s.) to another and the printing it to the file.
void Fileoutkey(char *res1, char *res2, int sys1, int sys2) //KANON
{
FILE *fp;
if(fp = fopen("task_out.cpp", "w"))
{
fprintf(fp, "%d: %s\n", sys1, res1);
fprintf(fp, "%d: %s\n", sys2, res2);
fclose(fp);
}
else
{
printf("No such file in directory.\n");
exit(1);
}
}
The function of converting (and it is OK)
int numSystem1 = 12;
char digits1 [13] = "0123456789AB";
char result1 [18] = "";
int digCount1 = 0;
while (num)
{
int rem1 = num % numSystem1;
result1 [digCount1] = digits1[rem1];
num /= numSystem1;
digCount1++;
for (int i = digCount1; i >= 0; i--)
{
cout << result1[i]; //here i get 10
}
}
When converting from 10 to 12 c.s. for, example, number 12 , instead of 10 I get 01.
Output in the console is right.
Conversion code definitely doesn't work. Taking your example of converting 12 from base 10 to base 12, the loop does the following:
First time around num is 12. 12 % 12 is 0 - so that is what is stored as the first character of your string. num is then divided by 12 to become 1.
Second time around 1 % 12 is 1 and that is added as the second character. This means your string now contains "01". Which is what you're seeing in your output - your code is adding the digits in reverse order.
You could either work out how big your number is and then count down from that to add the characters in the other direction or reverse the string using.
And also after the loop you need to add the NUL terminator character like this:
result1 [digCount1] = '\0';

N permutations of string (with repetitions)

I have to print first n permutations with repetitions of a string.
String is formed with characters 'a','b','c','d','e','f'.
For example, first 10 permutations would be: aaaaaa,aaaaab,aaaaac,aaaaad,aaaaae,aaaaaf,aaaaba,aaaabb,aaaabc,aaaabd.
This is my failed attempt:
int main()
{
FILE *c;
c = fopen("C:\\Users\\Korisnik\\Desktop\\tekst\\permutacija.txt", "w");
char s[6] = "abcdef";
char t[6] = "aaaaaa";
s[6] = '\0';
t[6] = '\0';
int k = strlen(t);
int m = k;
int n;
scanf("%d", &n);
int br = 0;
int i = 0;
while (br < n) {
i = 0;
while (i < 6) {
t[k-1] = s[i];
fprintf(c, "%s ", t);
fprintf(c, "\n");
i++;
br++;
if (br == n) {
exit(1);
}
}
t[k-1] = 'a';
k--;
if (k < 0) {
k = m;
}
}
return 0;
}
And my output for first 10 permutations is:
aaaaa
aaaaab
aaaaac
aaaaad
aaaaae
aaaaaf
aaaa
aaaaba
aaaaca
aaaada
Any suggestions?
(Showing a different idea)If you look carefully you will see that all the permutations are the numbers in base-7. Consider a as 0, b as 1 and so on. So for every number 1..n you will convert it into base 7 and write it (By write it I mean, in place of 0 you put a,1 - b etc). That will give you the required result. (Ofcourse in conversion you will have to append 0 to the left of the number as per number of digits you want to show). There are problems in your code:
char s[6]="abcdef";
is legal in C.
s[6]=0;
This is not as you are accessing array index out of bound which is Undefined behavior. strlen(t) is undefined behavior as t is not NUL terminated.
Also you have fprintf(c,"%s ",t); in your code - this also leads to undefined behavior, it also expects a char* which points to a nul terminated char array. This will make your realize that how irrelevant it is to have something like this
char s[6]="abcdef";
Long story short, use char s[7]="abcdef"; (same applies to t also).

Resources