I have been trying to find a solution for a long time but it seems like i cant.
I was trying to make a program that reads sentences from a file, puts the sentences as strings it into multidimensional array and quicksorts the array sentences alphabetically. Then it puts that array into an another array which shows the frequency of letters in a column position which shows the letter and frequency.
For example sentence 7 "CUD" would be row 7 and have a 1,1 and 1 in columns 3(c) 4(d) and 21(U). This works perfectly except for the last sentence which for some reason doesn't enter at all and shows random numbers.
void isAnAnagram(char anagramTester[][MAX_CHAR]) {
int countLetters[MAX_LINES][26] = {0};
int x;
for (int i =1; i <=MAX_LINES; i++) {
for (int j = 0; (anagramTester[i][j] != '\0'); j++) {
if (anagramTester[i][j] >= 'a' && anagramTester[i][j] <= 'z') {
x = anagramTester[i][j] - 'a' +1;
countLetters[i][x]++;
} else if (anagramTester[i][j] >= 'A' && anagramTester[i][j] <= 'Z') {
x = anagramTester[i][j] - 'A' +1;
countLetters[i][x]++;
}
}
}
for(int i=1;i<=MAX_LINES;i++){ //Rows
printf("row:%d ", i);
for(int j=1;j<=26;j++){ //Cols
printf("%d ",countLetters[i][j]);
}
printf("\n");
}}
This is the function which accepts a 2 dimensional array with strings in it
I have tried changing the loops but fundamentally I don't know why this error is only occurring in the last sentence.
here is the file input and output function
void readSentences(char inputSentences[][MAX_CHAR]){
int lineNum = 0;
FILE *fp = fopen("YOurDETAILS/input.txt", "r+");
fseek(fp, 0, SEEK_SET);
if(fp== NULL ){
/* check does weather file exist etc*/
perror("Error opening file");
lineNum = -1;
/* use this as a file not found code */
}
else {
// fgets returns NULL when it gets to the end of the file
for(lineNum = 1; lineNum <= MAX_LINES; lineNum++){
if(fgets(inputSentences[lineNum], MAX_CHAR, fp) != NULL){
inputSentences[lineNum][MAX_CHAR] = '\0';
}
else {
inputSentences[lineNum][MAX_CHAR] = '\0';
fclose(fp);
}
inputSentences[MAX_LINES][MAX_CHAR] = '\0';
}
}
}
void writeAnswer(char output[][MAX_CHAR]){
FILE *fp = fopen("YOurDETAILS/output.txt", "w");
fprintf(fp,"Sorted Array:\n");
for (int i =1; i <= MAX_LINES; i++) {
fprintf(fp,"sentence %d:%s \n ", i, output[i]);
}
fclose(fp);
}
the contents of the input.txt file are
cat
O, Draconian devil! Oh, lame saint!
tac
Tom Marvolo Riddle
Software engineering
Leonardo da Vinci! The Mona Lisa!
Computer science
CUD
Act
cuddle
Hey there!
Old Immortal dovers
I am Lord Voldemort
duck
the sorting file is
void swap(char sentencesToSwap[][MAX_CHAR], int i, int j){
for(int x = 0;x < MAX_CHAR; x++ ) {
char temp = sentencesToSwap[i][x];
sentencesToSwap[i][x] = sentencesToSwap[j][x];
sentencesToSwap[j][x] = temp;
}
}
void quicksort(char sentencesToSort[][MAX_CHAR], int first, int last){
if(first < last){
char pivotindex = partition(sentencesToSort, first, last);
quicksort(sentencesToSort, first, pivotindex-1);
quicksort(sentencesToSort, pivotindex+1, last);
}
}
int partition(char sentencesToSort[][MAX_CHAR], int first, int last){
swap(sentencesToSort, first, (first + last) / 2);
char *pivot;
pivot = sentencesToSort[first]; // remember pivot
int index1 = first + 1; // index of first unknown value
int index2 = last; // index of last unknown value
while (index1 <= index2) { // while some values still unknown
if (strcasecmp(sentencesToSort[index1],pivot) <= 0)
index1++;
else if (strcasecmp(sentencesToSort[index2],pivot) > 0)
index2--;
else {
swap(sentencesToSort, index1, index2);
index1++;
index2--;
}
}
swap(sentencesToSort, first, index2); // put the pivot value between the two
// sublists and return its index
return index2;
}
The main file is below
char sentences[MAX_LINES][MAX_CHAR];
readSentences(sentences);
isAnAnagram(sentences);
quicksort(sentences, 0, MAX_LINES );
writeAnswer(sentences);
Hi so im preety new to coding and I have recently hit a brickwall
This program has a segmentation fault debug and I think it has to do with allocating space for the buffer array or the input file , as those kept popping up as solutions in my search for an answer.
If you know what I did wrong I would appreciate if you told me rather than giving me the solution. Also Im completely lost on how to allocate memory to anything , so it would be great if someone explained how to allocate memory in context to the code.
It is supposed to read a file structured like this
2
3 4
3 4
where 2 = how many files are downloading, 3 = the Kb/s of file( each line represents a file) , and 4 = time remaining until done. The program is supposed to output a file out that has the time needed for all the things to download(mind you when a file finishes the speed goes up to others)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
FILE *in = fopen("download.in", "r");
FILE *out = fopen("download.out", "w");
int i, n, j, a, k, o;
char buffer[100];
fgets(buffer, 10, in);
sscanf(buffer, "%d", &n);
int tn[n];
int xn[n];
i = 0;
while (i < n) {
fgets(buffer, 100, in);
sscanf(buffer, "%d %d", &tn[i], &xn[i]);
++i;
}
for (i = 0; i < n; ++i){
for (j = i + 1; j < n; ++j){
if (tn[i] > tn[j]){
a = tn[i];
tn[i] = tn[j];
tn[j] = a;
a = xn[i];
xn[i] = xn[j];
xn[j] = a;
}
}
}
i = 1;
float b ;
k = 0;
o = 1;
while(o < n){
if(xn[o] == xn[o - 1]){
k = tn[o] + tn[o - 1]
;
}
else{
b = (tn[o] * xn[o]) / (tn[o] + tn[o - 1] + k);
k = 0;
}
++o;
}
fprintf( out, "%f", b );
fclose(in); fclose(out);
return 0;
}
I know the answer it gives is not accurate but I want to fix the segmentation fault first then deal with that
gdb r then gdb bt returns this
(gdb) r
Program received signal SIGSEGV, Segmentation fault.
_IO_fgets (buf=0x7fffffffeb30 "", n=10, fp=0x7fffffffeac0) at iofgets.c:50
50 iofgets.c: No such file or directory.
(gdb) bt
#0 _IO_fgets (buf=0x7fffffffeb30 "", n=10, fp=0x7fffffffeac0) at iofgets.c:50
#1 0x0000000000400766 in main () at main.c:11
codeblocks says the code is ok and the site I am trying to give this says there is a segmentation fault aswell.
Here is code with segfault fixed. I had to (1) specify absolute path and (2) change the loop to a for loop.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
FILE *in = fopen("/home/developer/CLionProjects/untitled4/download.in", "r");
FILE *out = fopen("/home/developer/CLionProjects/untitled4/download.out", "w");
int i, n, j, a, k, o;
char buffer[100];
fgets(buffer, 10, in);
sscanf(buffer, "%d", &n);
int tn[n];
int xn[n];
for (i = 0; i < n; i++) {
if (!fgets(buffer, 100, in)) break;
if (sscanf(buffer, "%d %d", &tn[i], &xn[i]) < 2) break;
}
for (i = 0; i < n; ++i) {
for (j = i + 1; j < n; ++j) {
if (tn[i] > tn[j]) {
a = tn[i];
tn[i] = tn[j];
tn[j] = a;
a = xn[i];
xn[i] = xn[j];
xn[j] = a;
}
}
}
i = 1;
float b;
k = 0;
o = 1;
while (o < n) {
if (xn[o] == xn[o - 1]) {
k = tn[o] + tn[o - 1];
fprintf(out, "Some number: %d\n", k);
} else {
b = (tn[o] * xn[o]) / (tn[o] + tn[o - 1] + k);
k = 0;
fprintf(out, "Some number: %d\n", k);
}
++o;
}
fclose(in);
const char *text = "Write this to the file";
fprintf(out, "Some text: %s\n", text);
fclose(out);
int c;
FILE *file;
file = fopen("/home/developer/CLionProjects/untitled4/download.out", "r");
if (file) {
while ((c = getc(file)) != EOF)
putchar(c);
fclose(file);
}
return 0;
}
My code needs to do three things:
Read numbers from a file FILE1 into an array (dynamic)
Sort those numbers
Search for numbers input from a FILE2 in the sorted array.
.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
int main (int argc, char *argv[]) {
FILE *fp1 = fopen ("myFile1.txt", "r");
if (fp1 == NULL) {
printf ("cannot open this file");
exit (0);
}
FILE *fp2 = fopen ("test1.txt", "w");
if (fp2 == NULL) {
puts ("Not able to open this file");
exit (1);
}
int i = 0, num, j, k;
int *B = NULL;
int *C;
int a;
int size = 32;
B = malloc (sizeof (int) * size);
while (fscanf (fp1, "%d", &num) == 1) {
if (i < size) {
B[i] = num;
fprintf (fp2, "%d\r\n", num);
i++;
}
else {
C = malloc (sizeof (int) * 2 * size);
memcpy (C, B, size * sizeof (int));
free (B);
B = &C[0];
B[i] = num;
i++;
size = size * 2;
i++;
for (j = 0; j < size; ++j) {
for (k = j + 1; k < size; ++k) {
if (B[j] < B[k]) {
a = &B[j];
B[j] = B[k];
B[k] = a;
}
}
}
printf ("after sorting");
for (j = 0; j < size; ++j)
printf ("%d\n", B[j]);
}
}
return 0;
fclose (fp1); /* note this code is never reached */
fclose (fp2);
}
I successfully complete the first part of reading in the numbers from a file. But I am not able to understand how to sort these numbers.
I am trying to apply bubble sort, but it puts 0s in my array. How is my implementation incorrect?
& is the address-of operator. You pass it as a pointer. You need a = B[i], since a is an int.
Now you sort the numbers descending, if you want them to be ascending change the < to > in if (B[j] < B[k]).
Also you must always check whether malloc succeeded or not with e.g.:
if (!B) {
fprintf(stderr,"B alloc error");
exit(-1);
}
Also you might want to consider realloc.
In addition there is a built-in qsort in stdlib.h, which gives much better time than O(n^2).
Note: I haven't tested your file operations, since you said they work properly.
I am trying to calculate the mode or the integer that appears the most for each line.
I get an print two values and then segmentation fault.
for (i = 0; i < count; i++) {
if (array[i]) {
int i, j, k, cnt = 1, p, big;
int b[MAX_NUM] = {0};
printf("count:%d\n", count);
for (i = 1; i <= array[i]; i++) {
for (j = i + 1; j <= array[i]; j++) {
if (array[i] == array[j])
printf("cnt:%d\n", cnt);
cnt++;
}
printf("cnt2:%d\n", cnt);
b[k] = cnt;
k++;
cnt = 1;
}
big = b[k];
p = 1;
for (i = 2; i <= array[i]; i++) {
if (big < b[i]) {
big = b[i];
p = i;
}
}
printf("The element that occurs offen is %d\n", array[p]);
printf("And it has occurred %d times\n", b[p]);
}
}
}
}
}
return 0;
}
EDIT:
See the look here in my code. The values that are printed are the numbers on each line of the file followed by a blank line like this:
1
2
3
4
5
6
5
4
5
14
62
48
14
1
3
5
7
9
123
456
789
1234
5678
34
34
34
34
34
1
1
2
2
2
2
2
3
3
4
4
4
4
5
5
6
7
7
7
1
1
Integers: 9
.....
You redefine i and p in an inner scope where they shadow current definitions. This is obviously unintentional as the for expression looks quite wrong:
if (array[i]) {
int i, j, k=1, cnt = 1, p, big;
// ^
// Redefinition of i.
// You should use a different name for the loop index below
// Same remark for p, it is safer to not redefine local variables
// in inner scopes. Any { starting a block creates a new scope
// in which variables can be defined, or in this case redefined.
...
for (i = 1; i <= array[i]; i++) {
...
for (i = 2; i <= array[i]; i++) {
...
In the same area of the code, you use k without a prior initialization.
The code to compute maximum occurrences can be put into a separate function and simplified this way:
#include <stdio.h>
// get the number of ocurrences of val in array a of size n
int get_number_of_occurrences(int a[], int n, int val) {
int cnt = 0, i;
for (i = 0; i < n; i++) {
if (a[i] == val)
cnt++;
}
return cnt;
}
// return the index for the number that occurs the most
int get_max_occurrence_index(int a[], int n) {
int p = 0, cnt, max = 0, i;
for (i = 0; i < n; i++) {
cnt = get_number_of_occurrences(a, n, a[i]);
if (max < cnt) {
max = cnt;
p = i;
}
}
return p;
}
int main() {
int i, n, a[20], max;
printf("Enter the maximum number of elements\n");
scanf("%d", &n);
printf("Enter the elements\n");
for (i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
i = get_max_occurrence_index(a, n);
max = get_number_of_occurrences(a, n, a[i]);
printf("The element that occurs most oftenly is %d\n", a[i]);
printf("And it has occurred %d times\n", max);
return 0;
}
If you want to use this logic in your original program, you should use it for each line as you read the file instead of at the end where it only applies to the last line. The line parsing code is incorrect too: you take the first digit's ASCII value as the value instead of parsing it with strtol().
Here is a corrected version:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX_NUM 1000
#define MAX_LINE_LEN 2048
#define N 100
void fatal(const char *msg) {
printf("%s\n", msg);
exit(1);
}
int main(int argc, char *argv[]) {
FILE *fp;
char filename[100];
char line[MAX_LINE_LEN];
char *p;
int array[MAX_NUM];
int index, count, max;
printf("Please enter the file name: \n");
if (scanf("%99s", filename) != 1) {
fatal("Error in entering file.");
}
if ((fp = fopen(filename, "r")) == NULL) {
fatal("Unable to open the file.");
}
while ((p = fgets(line, MAX_LINE_LEN, fp)) != NULL) {
/* skip white space */
p += strspn(p, " \t\n");
if (*p == '#' || *p == '\0') {
/* ignore comment and blank lines */
continue;
}
/* scan and convert the numbers */
for (count = 0; *p != '\0'; ) {
if (isdigit((unsigned char)*p)) {
array[count++] = strtol(p, &p, 10);
printf("%d\n", array[count]);
} else {
/* skip to next space or end of string */
p += strcspn(p, " \t\n");
}
/* skip white space after the number */
p += strspn(p, " \t\n");
}
index = get_max_occurrence_index(array, count);
max = get_number_of_occurrences(array, count, array[index]);
printf("The element that occurs most often is %d\n", array[index]);
printf("And it has occurred %d times\n", max);
}
fclose(fp);
return 0;
}
Maybe i just can not see through your code, but at no point do i see you loading the actual numbers from your file into any variable or array to work with.
You are loading a line with while ((p = fgets(line, MAX_LINE_LEN, fp)) != NULL) {
Inside that loop, you are breaking this line into tokens to count how many numbers you have.
As far as i can see, array[count]++; is used to count how many numbers are in each line. Using the index as the line number.
You should start by thinking about how to get your data into a usable format
You can start trying to load the values into a 2 dimensional array.
Using the first dimension for the line number and the second for the values.
If you don't understand your code well enough, you should start with more comments
What do you use your difines and variables for.
#define MAX_NUM 1000 //maximum number of lines
int array[MAX_NUM] = {0}; //index refers to line number of file. used to count numbers in each line.
// read file line by line, split every line into tokens to count amount of numbers
while ((p = fgets(line, MAX_LINE_LEN, fp)) != NULL) {
if (count >= MAX_NUM) {
fatal("Array error");
}
if (line[0] != '#') {
p = strtok(line, " ");
while (p != NULL) {
if (isdigit(*p)) {
array[count]++;
}
p = strtok(NULL, " ");
}
}
count++;
//printf("COUNT:%D\n", count);
}
Choosing good variable names in addition would be even better
#define MAX_NUM 1000 -> #define MAX_LINE_NUM 1000
I have no idea about what your variables int i, j, k, cnt = 1, p, big; do.
Give them better names and or comment them. Will not only help you, but your helpers that need to understand what you intend to do with them.
First i thought you needed help with the algorithm for the mode so i wrote this first:
Using very basic stuff to keep it as simple as possible.
Would be cleaner to put it into functions if you know how.
Did not use functions since it seems you do not know completely how to work with them (you should look into that)
This algorithm is doing the following:
Take the first number in the array
Run through the array and everytime you find that number, you increase a counter
Save the number and the count as highest and highestCnt
Repeat with every number in the array and overwrite highest and highestCnt whenever count > highestCnt
When there are multiple number with the highest occurrence it will only remember the number that was counted first. If you want to return all numbers with the highest occurrence, the coude would need to be changed.
Could do something like checking if count == highestCnt and then set something so you know there is no single number with the highest count until you find one with an even higher count.
#include<stdio.h>
#define sizea 100
int main(void) {
int array[sizea] = { 1,3,6,8,3,6,7,4,6,9,0,3,5,12,65,3,76,5,3,54,
1,3,6,89,3,6,7,4,6,9,0,4,5,12,65,3,76,5,3,54,
1,9,6,8,3,45,7,4,6,9,0,89,5,12,65,3,76,5,3,54,
6,3,6,8,3,6,7,4,6,9,0,23,5,12,65,3,76,5,3,54,
1,3,6,90,3,6,7,4,6,9,0,5,5,12,65,3,76,5,3,54 };
int number;
int count = 1;
int highest = 1;
int highestCnt = 1;
int end = sizea - 1; //end defines at what element in the array the loop will end
int j; //j is used to load a number that will be count
int i; //i is used run through the array and compare every number the the one that is being count
for (j = 0; j <= end; j++) {
number = array[j]; // load a number to count
count = 1; // start counting at 1
for (i = j+1; i <= end; i++) {
// if we find the same number again, we increase the counter
// then we load the last element into the current array position
// then we change decrement "end" by 1
// this is like throwing out all the numbers we allready count
// using while instead of if so it will check the last element that was moved to current position as well
// check for i <= end so it doesnt count twice when the last element equals our number
while (array[i] == number && i <= end) {
count++;
array[i] = array[end];
end--;
}
}
// if the count of the number is highers the the previus highest, it's obviously our new highest count.
if (count > highestCnt) {
highest = number;
highestCnt = count;
}
}
printf("number: %i, count: %i", highest, highestCnt);
}
I have a program to develop but I'm having some difficulties in one part.
I have to read a number of tests (t) that will be made. After that I must read a number (n) of columns and rows to make a square matrix² (nxn). After instance of the matrix, the program must populate it from the input of the user. The user will type ., b or w. Based in this pattern I have to populate the matrix. Each line that the user will type must contain n characters (., b or w) and he will type n times. This will fill the matrix (n characters by n lines). Can you guys give me a hand?
This is the code I have:
int main(void)
{
//vars
int n = 0, t = 1, x = -1, y = -1, teste = 1;
int i,j;
//Start
scanf(" %d %*c",&t);//scans t
while (t-- > 0) {
scanf(" %d", &n);//scans n
if(n>0 && n < 100){
int table[n][n];//the matrix n x n
for (i = 0; (i < n);++i) {//iterator to lines
char l[n];
scanf ("%s", l); //scans a line
for (j = 0; j < n; ++j) {//iterator to colums
//these ifs are to identfy the input
if (l[j] == 'b'){
table[i][j]=1;
}else if(l[j] == 'w'){
table[i][j]=2;
x=j;y=i;
}else{
table[i][j]=0;
}
}
}
}
return 0;
}
I made the exactly same thing in Java and it worked. Where am I failing?
Your variable l doesn't allow enough space to store the null at the end of the string. You are therefore overflowing into some other variable, and that may be affecting all sorts of things.
You should probably read the line into a far larger string, and make sure it is the correct length. You should also error check each read operation; you should also report invalid characters in the input.
This code works for me. Note the way it echoes data so it is possible to see what's going wrong. Error reporting should really be to standard error; I've been lazy.
#include <stdio.h>
#include <string.h>
static void dump_board(FILE *fp, const char *tag, int n, int table[n][n])
{
fprintf(fp, "%s: (%d x %d)\n", tag, n, n);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (table[i][j] == 0)
putc('=', fp);
else if (table[i][j] == 1)
putc('B', fp);
else if (table[i][j] == 2)
putc('W', fp);
else
putc('?', fp);
}
putc('\n', fp);
}
}
int main(void)
{
int n = 0, t = 1, x = -1, y = -1;
if (scanf(" %d %*c", &t) != 1)
{
printf("Failed to read t\n");
return 1;
}
printf("%d data sets\n", t);
while (t-- > 0)
{
if (scanf(" %d", &n) != 1)
{
printf("Failed to read n\n");
return 1;
}
printf("Size of data set: %d x %d\n", n, n);
int c;
while ((c = getchar()) != EOF && c != '\n')
;
if (n > 0 && n < 100)
{
int table[n][n];
for (int i = 0; i < n; i++)
{
char line[4096];
if (fgets(line, sizeof(line), stdin) == 0)
break;
int len = strlen(line);
if (line[len-1] != '\n')
{
printf("Format error: line too long (%d bytes)\n", len);
return 1;
}
line[--len] = '\0';
if (len != n)
{
printf("Format error: line <<%s>> is not length %d\n", line, n);
return 1;
}
for (int j = 0; j < n; ++j)
{
if (line[j] == 'b')
table[i][j] = 1;
else if (line[j] == 'w')
{
table[i][j] = 2;
x = j;
y = i;
}
else if (line[j] == '.')
table[i][j] = 0;
else
{
printf("Format error: invalid character %c\n", line[j]);
return 1;
}
}
}
dump_board(stdout, "Input", n, table);
printf("Last white piece at (%d,%d)\n", x, y);
}
}
return 0;
}
Input
2x
4
b..w
.bw.
.b.b
w.w.
8
b.w.b.w.
.w.b.w.b
bbwwbbww
b......w
ww....bb
bwb..wbw
bbbbwwww
........
Output
2 data sets
Size of data set: 4 x 4
Input: (4 x 4)
B==W
=BW=
=B=B
W=W=
Last white piece at (2,3)
Size of data set: 8 x 8
Input: (8 x 8)
B=W=B=W=
=W=B=W=B
BBWWBBWW
B======W
WW====BB
BWB==WBW
BBBBWWWW
========
Last white piece at (7,6)