Empty lines/characters when reading text file using strsep() - c

I'm learning C and as a practice, I'm trying read a file with different sets of numbers in each line, and print (or save to a different file) each number per line (also as string).
You can see the code here:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 40
int main(){
char numbers[SIZE];
FILE *fileRead;
FILE *fileWrite;
char *token, *tofree, *str;
fileRead = fopen("/Users/USER/Documents/readfile.txt", "r");
if (fileRead==NULL){
printf("File not found\n");
return 1;
}
fileWrite = fopen("/Users/USER/Documents/writefile.txt", "w");
if (fileWrite==NULL){
printf("File not found\n");
return 1;
}
while (!feof(fileRead)){
fgets(numbers, SIZE, fileRead);
tofree = str = strdup(numbers);
while ((token = strsep(&str, " \n"))) fprintf(fileWrite,"%s\n", token);
free(tofree);
}
puts("Succeed");
return 0;
}
When I remove the '\n' character at printing/writing, all the numbers are printed one after the other. I expected that.
The problem is that when I include the \n char, the output includes some empty lines. I include an example of the input and the output files:
Input:
43 19 01 23 05 28 35
41 32 20 19 28 34 07
25 02 36 04 18 23 43
15 41 45 36 32 26 11
13 32 23 09 14 12 36
18 43 03 24 08 13 20
23 12 21 03 27 36 17
09 01 23 17 22 20 33
11 01 18 19 14 02
30 16 39 44 32 03
36 40 25 41 05 44
02 20 06 08 41 43
13
15
Output:
43
19
01
23
05
28
35
41
32
20
19
28
34
07
25
02
36
04
18
23
43
15
41
45
36
32
26
11
13
32
23
09
14
12
36
18
43
03
24
08
13
20
23
12
21
03
27
36
17
09
01
23
17
22
20
33
11
01
18
19
14
02
As you can see, the output includes an empt line when the original file had a newline, but if I remove the \n, it prints/writes just one number after other without space:
4319012305283541322019283407250236041823431541453632261113322309141236184303240813202312210327361709012317222033110118191402301639443203364025410544022006084143210219201733320528113826140803412735352236132117381233133230312645364405180322300236422806112726081307442523112145041827394426382243380510372504360104250602164226284117350617433404412518161910373624201317450344241202013435071104422329080106090526224243142223331215143012373820100331390117334234164401454327114125153130103225420930240137274114261206431112330135024321053027451435420809430807370327140127112337412506030824420320113615214544383436282305210401363805453529341319224405160121111525171338310322033738183632421824451732341905182302233945312133194425134030260524
What character is being inserted if \n is an explicit delimiter?

Related

Weird Output in for loop in C (Repetitive numbers)

This is my code for finding prime numbers.
int main (void){
int p, d;
_Bool isprime;
for (p=2;p<=50;++p){
isprime = 1;
for (d=2;d<p;++d){
if (p%d == 0)
isprime = 0;
if (isprime != 0)
printf("%i ", p);
}
}
return 0;
}
The output of this program is
3 5 5 5 7 7 7 7 7 9 11 11 11 11 11 11 11 11 11 13 13 13 13 13 13 13 13 13 13 13 15 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 21 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 25 25 25 27 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 33 35 35 35 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 39 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 45 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 49 49 49 49 49
The numbers seem to be right, but they are repetitive. Is there something wrong with my code? Or is there something wrong with the compiler? Every time I use a for loop (not just this program) the output is like this. How do I fix this?
Thanks in advance!(Sorry for my bad English)
The problem with your code, is that it prints p multiple times, for the same value of p. Like Eugene Sh. stated in a comment, it's easily fixed by moving the if statement up a level, to the outer for loop. I also changed is_prime to a bool value, and edited how it's set.
int max_p = 50;
int p, d;
bool is_prime;
for (p = 2; p <= max_p; ++p) {
is_prime = true;
for (d = 2; d < p; ++d) {
if (p % d == 0) {
is_prime = false;
break;
}
}
if (is_prime) {
printf("%i ", p);
}
}
I will assume that I used C++ doesn't make a difference.
Others have given tips. Some of them are useful, some of them are not. The end goal is to print all prime numbers only. So checking if the number 6 is prime, we start with d = 2. So we check 6 % 2. Well that is equal to 0. We know that 6 is NOT prime. We should move on to 7. Instead we have incremented 2 to 3 and now we check again. 6 % 3... we do this for every number less than the number we are trying to check. This greatly adds to the computational complexity. This program runs very close to BigTheta(n^2). An easier way to run this would be a do-while loop or through the use of a break statement. Since you're using C, use an int as a bool marker (to prevent another lib import). Your inner loop would look like this:
int is_prime = 1;
for (d = 2; d < p; d++)
{
if (p % d == 0)
{
is_prime = 0
break;
}
}
if (is_prime)
printf("%d ", p);
There are additional methods of reducing the complexity, but those rely on better algorithm design moreso than more efficient code. For a beginner's project, think about why the current version of your code is inefficient (even if it was working properly). A lot of it comes with experience, but you shouldn't neglect individual code- and algorithm review.
You need to put your printf lines outside your inner loop.
Like this:
int main (void)
{
int p, d;
_Bool isprime;
for (p=2;p<=50;++p){
isprime = 1;
for (d=2;d<p;++d){
if (p%d == 0) {
isprime = 0;
break;
}
}
if (isprime)
printf("%i ", p);
}
return 0;
}
You have to use break statement. Without break, every time the calculation is performed, thus so many repetition in your original code. But even with break statement your code will generate many non desirable numbers/output instead of just generating prime numbers. So i have written following code for you. It will generate prime numbers as per your question.
Use the following code for generating prime numbers upto 50.
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int prime,i,k,j,max;
printf("2\n");
printf("3");
for(i=4; i<max; i++)
{
if(i%2!=0 && i%3!=0 && i%5!=0 && i%7!=0)
{
prime=i;
printf("\n%d",prime);
k++;
}
}
}

Does scanf break on gigantic char tables?

I have a problem with reading string of triples digit-digit-space.
Relevant code (lib's may / may not be needed in this particular code):
#include <stdio.h>
#include <stdlib.h>
#define N 20
#define M 20
#define n (3*N*M)
int main()
{
char str_t[n];
scanf("%s", str_t);
for(i=0;i<n;i++)
printf("%c", str_t[i]);
return 0;
}
The input is as mentioned set of triples repeated 399 times finished with d-d, saved to char array[1200].
I assume that pasting into console is okay since I did it before. When it comes to printing back the array, I get random mumbo jumbo like: 3�X2���W2��#M!�
Input:
08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 49 49 99
40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 81 49 31 73 55 79
14 29 93 71 40 67 53 88 30 03 49 13 36 65 52 70 95 23 04 60 11 42 69
24 68 56 01 32 56 71 37 02 36 91 22 31 16 71 51 67 63 89 41 92 36 54
22 40 40 28 66 33 13 80 24 47 32 60 99 03 45 02 44 75 33 53 78 36 84
20 35 17 12 50 32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38
64 70 67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21 24
55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72 21 36 23 09
75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95 78 17 53 28 22 75 31
67 15 94 03 80 04 62 16 14 09 53 56 92 16 39 05 42 96 35 31 47 55 58
88 24 00 17 54 24 36 29 85 57 86 56 00 48 35 71 89 07 05 44 44 37 44
60 21 58 51 54 17 58 19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77
04 89 55 40 04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98
66 88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69 04 42
16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36 20 69 36 41 72
30 23 88 34 62 99 69 82 67 59 85 74 04 36 16 20 73 35 29 78 31 90 01
74 31 49 71 48 86 81 16 23 57 05 54 01 70 54 71 83 51 54 69 16 92 33
48 61 43 52 01 89 19 67 48
From http://linux.die.net/man/3/scanf, concerning the %s format:
Matches a sequence of non-white-space characters... The input string
stops at white space
If the input consists of a single line, you can use fgets instead of scanf:
fgets(str_t, n, stdin);

Populating 2d array of ints from string in C

I want to populate a 2d array of ints with some numbers.
The numbers is in a grid format like the following :
08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48
I want my program to take the string above and store the numbers in a 20x20 2d array of ints.
int main(void)
{
int grid[20][20];
for(int i = 0;i<20;i++)
{
for(int j = 0;j<20;j++)
{
grid[i][j] = //some code to populate int here
}
}
}
I am unsure how to get the 'code to populate'
So I tried using strtok as below:
int main(void)
{
char *input = "08 02 22...48";
char *output = strtok(input," ");
printf("%s",output);
}
However, the above is giving me a segmentation fault and I am unsure why.
I am very new to programming, especially in C, and I am a bit unsure how to get an input like above stored as a 2d array of ints. Any alternative routes to the above or any guidance as to why I am getting segmentation faults is appreciated, thanks :)
You're almost there. Inside your inner loop,
if (scanf("%d", &grid[i][j]) < 1)
break; // oops, looks like we ran out of numbers to read!
The reason that strtok is giving you a segmentation fault is that you are using a const char* as the input, but strtok expects to modify the string (namely, it inserts a '\0' at the first instance of the terminating character). If you just changed your code to
char input[] = "08 02 22...48";
char *output = strtok(input," ");
printf("%s",output);
You would find that it works (because that initializer creates a string that is not a const).
Obviously you can then use sscanf to convert the string to a numerical value - make sure that you pass it the address of the location where you want to store:
sscanf(output, "%d", &grid[i][j]);
You look like you know how to combine these elements into a loop structure. Do note that strtok should be called with a char* argument the first time, and with NULL after that...
EDIT re-reading your question, it seems you would benefit from a complete code example:
#include <stdio.h>
#include <string.h>
int main(void) {
char input[]=\
"08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 "\
"49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 "\
"81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65 "\
"52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91 "\
"22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80 "\
"24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50 "\
"32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70 "\
"67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21 "\
"24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72 "\
"21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95 "\
"78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92 "\
"16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57 "\
"86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58 "\
"19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40 "\
"04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66 "\
"88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69 "\
"04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36 "\
"20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16 "\
"20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54 "\
"01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48";
int ii, jj;
int grid[20][20];
char *s = strtok(input, " ");
for(ii=0; ii<20; ii++){
for(jj=0; jj<20; jj++){
sscanf(s, "%d", &grid[ii][jj]);
s = strtok(NULL, " ");
}
}
for(ii=0; ii<20; ii++){
for(jj=0; jj<20; jj++){
printf("%02d ", grid[ii][jj]);
}
printf("\n");
}
return 0;
}
Let me know if any of this needs clarification.
You may not apply function strtok to string literals. There is a more simple and robust approach by means of function strtol .
Here is a demonstrative program
#include <stdio.h>
#include <stdlib.h>
#define N 20
int main(void)
{
char *s =
"08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 "
"49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 "
"81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65 "
"52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91 "
"22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80 "
"24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50 "
"32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70 "
"67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21 "
"24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72 "
"21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95 "
"78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92 "
"16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57 "
"86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58 "
"19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40 "
"04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66 "
"88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69 "
"04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36 "
"20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16 "
"20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54 "
"01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48 ";
int a[N][N] = { { 0 } };
int *p = ( int * )a;
const char *nptr = NULL;
char *endptr = s;
for ( size_t i = 0; i < N * N && nptr != endptr; i++ )
{
int x;
nptr = endptr;
x = ( int ) strtol( nptr, &endptr, 10 );
if ( nptr != endptr ) p[i] = x;
}
for ( size_t i = 0; i < N; i++ )
{
for ( size_t j = 0; j < N; j++ ) printf( "%3d", a[i][j] );
puts( "" );
}
return 0;
}
And this is its output
8 2 22 97 38 15 0 40 0 75 4 5 7 78 52 12 50 77 91 8
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 4 56 62 0
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 3 49 13 36 65
52 70 95 23 4 60 11 42 69 24 68 56 1 32 56 71 37 2 36 91
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
24 47 32 60 99 3 45 2 44 75 33 53 78 36 84 20 35 17 12 50
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
67 26 20 68 2 62 12 20 95 63 94 39 63 8 40 91 66 49 94 21
24 55 58 5 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
21 36 23 9 75 0 76 44 20 45 35 14 0 61 33 97 34 31 33 95
78 17 53 28 22 75 31 67 15 94 3 80 4 62 16 14 9 53 56 92
16 39 5 42 96 35 31 47 55 58 88 24 0 17 54 24 36 29 85 57
86 56 0 48 35 71 89 7 5 44 44 37 44 60 21 58 51 54 17 58
19 80 81 68 5 94 47 69 28 73 92 13 86 52 17 77 4 89 55 40
4 52 8 83 97 35 99 16 7 97 57 32 16 26 26 79 33 27 98 66
88 36 68 87 57 62 20 72 3 46 33 67 46 55 12 32 63 93 53 69
4 42 16 73 38 25 39 11 24 94 72 18 8 46 29 32 40 62 76 36
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 4 36 16
20 73 35 29 78 31 90 1 74 31 49 71 48 86 81 16 23 57 5 54
1 70 54 71 83 51 54 69 16 92 33 48 61 43 52 1 89 19 67 48
#include <stdio.h>
#include <ctype.h>
int populate(const char **p){
int n = 0;
while(isspace(**p))
++*p;
for(n=0; isdigit(**p); ++*p)
n = n * 10 + **p - '0';
return n;
}
int main() {
const char *numbers =
"08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 "
"49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 "
"81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65 "
"52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91 "
"22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80 "
"24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50 "
"32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70 "
"67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21 "
"24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72 "
"21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95 "
"78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92 "
"16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57 "
"86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58 "
"19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40 "
"04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66 "
"88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69 "
"04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36 "
"20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16 "
"20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54 "
"01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48";
const char *p = numbers;
int grid[20][20];
for(int i = 0;i<20;i++){
for(int j = 0;j<20;j++){
grid[i][j] = populate(&p);
printf("%02d ", grid[i][j]);
}
printf("\n");
}
return 0;
}

Runtime error in codechef practice questions

I'm getting "sigsegv" , a runtime error from the following code when i try to run it on codechef while the code works fine on my computer with various test inputs.I've also kept in mind the constraints given in the problem but I'm still unable to debug it. The question is not from any contest but a practice problem . Please point out any mistake you can find .
Actual codechef question
#include<stdio.h>
int cash[101][101]={0};
int rec[101][2];
int ri=0;
int sumx(int mat[101][101],int i,int j,int lines)
{
int n=0,a=0,b=0;
if(cash[i][j]!=0)
{
return cash[i][j];
}
else if(i==lines-2)
{
n=(mat[i+1][j]>mat[i+1][j+1])?mat[i+1][j]:mat[i+1][j+1];
cash[i][j]=n+mat[i][j];
rec[ri][0]=i;
rec[ri++][1]=j;
return n+mat[i][j];
}
else
{
a=sumx(mat,i+1,j,lines);
b=sumx(mat,i+1,j+1,lines);
n=(a>b)?a:b;
cash[i][j]=n+mat[i][j];
rec[ri][0]=i;
rec[ri++][1]=j;
return n+mat[i][j];
}
}
int main()
{
int i=0,k=0;
int lines=0,n=0;
int r=0;
int tc=0;
int mat[101][101];
scanf("%d",&tc);
while(tc--)
{
scanf("%d",&lines);
i=0;
k=0;
while(i<lines)
{
while(k<=i)
{
scanf("%d",&mat[i][k]);
k++;
}
k=0;
i++;
}
if(lines==1)
{
r=mat[0][0];
}
else
{
r=sumx(mat,0,0,lines);
}
i=0;
while(i<ri)
{
cash[(rec[i][0])][(rec[i][1])]=0;
rec[i][0]=0;
rec[i][1]=0;
i++;
}
ri=0;
printf("%d\n",r);
}
return 0;
}
The error is with lines
while(i<ri)
{
cash[(rec[i][0])][(rec[i][1])]=0;
rec[i][0]=0;
rec[i][1]=0;
i++;
}
the values of rec[i][0] rec[i][1] can be undefined in some cases ie they may return garbage values
You can Use memset instead to change the values to 0
memset(rec,0,sizeof(rec));
memset(cash,0,sizeof(cash));
I ran your solution , there's a bug in your algorithm implementation try finding it yourself
I can provide you a test case(using a testcase generator) for which it fails
21
79
89 28
14 6 63
96 58 67 48
80 8 22 27 8
24 21 23 96 97 72
38 90 95 83 57 60 94
13 96 9 24 65 27 67 40
26 20 58 42 29 8 52 49 37
80 65 65 34 79 10 89 11 20 84
57 59 72 79 51 67 84 70 43 62 96
16 4 18 9 5 40 34 2 15 4 28 50
29 1 60 39 28 92 38 65 95 57 10 71 37
25 78 96 43 17 51 88 19 0 30 20 80 39 35
55 41 63 76 4 20 97 72 43 93 76 11 82 33 25
61 85 41 77 42 90 20 5 69 51 4 54 41 18 83 72
12 56 21 82 7 1 84 26 47 26 22 52 84 39 75 70 89
12 39 83 92 49 20 35 20 31 96 66 75 48 79 13 51 49 50
42 81 0 58 70 40 16 83 27 34 79 64 14 26 19 22 38 55 93
64 81 26 29 47 22 73 61 3 2 61 99 18 43 33 10 13 46 24 53
5 56 0 0 3 0 71 12 82 34 17 11 14 51 1 82 73 53 85 75 89
correct answer is 1431 while your code returns 1299
#Randomizer : The code runs fine with the output as 1431 , not 1299 . Anyways , as you suggested about the garbage being generated from rec[i][0] rec[i][1], It never appeared to me that rec[i][0] rec[i][1] could be generating garbage as I only accessed the used up cells . However , memset eliminated the need of rec , so cash was easily reset to zero . All i did was remove the rec matrix and reset cash using memset and the code ran fine on codechef. I couldn't figure out how it could be generating garbage , still , its accepted on codechef since I removed rec part . Thank you for the help.

unsigned char comparision

i have a problem with the attached code. i wish to replace some delimiters with offsets(the amount of bytes between them). i have only 1 byte and if the offset is larger then 254 i wanna replace it with 255. in this case the next found offset should not be replaced. the replace part works fine... anyhow i can't recognize whether the last delimiter was replaced with 255 last time or not, it is skipped or converted and i dont know why/what am i doing wrong. Maybe anyone could give me any clue. here the code and at the end the output. i have marked (with **) the delimiter, that should not be replaced.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include "zlib.h"
unsigned char *process(unsigned char *data, unsigned long size )
{
int i;
unsigned char *lastdel = data+1;
for (i=2;i<size; i++)
{
// if((unsigned char)*lastdel >254 )printf(" %c <#######-------\n", *lastdel);
//if(*lastdel == (unsigned char) 255 )printf(" %c <#######-------\n", *lastdel);
//if (!memcmp(lastdel,(unsigned char) 255, 1))
//printf(" %c <#######-------\n", *lastdel);
//if(*lastdel == (unsigned char) 255 )printf(" %c <#######-------\n", *lastdel);
//if(data[i] !='\x03' && data[i] !='\x1D' && data[i] !='\x1E'&& data[i] !='\x1C')continue;
//if(*lastdel >(unsigned char) 254 )printf(" %c <#######-------\n", *lastdel);
if(*lastdel >(unsigned char) 254 )printf(" %c <++++~~~++++++++#######-------\n", *lastdel);
if(data[i] =='\x03')
{
*lastdel = (&data[i] - lastdel-1 >255) ?(unsigned char) 255 : &data[i] - lastdel-1;
i+=2;
lastdel = &data[i];
continue;
}
if(data[i] =='\x1D')
{
*lastdel = (&data[i] - lastdel-1 >255) ?(unsigned char) 255 : &data[i] - lastdel-1;
i++;
lastdel = &data[i];
continue;
}
if(data[i] =='\x1E'|| data[i] =='\x1C')
{
if(*lastdel >(unsigned char) 254 )printf(" %c <++++~~~++++++++#######-------\n", *lastdel);
*lastdel = (&data[i] - lastdel-1 >255) ? (unsigned char) 255 : &data[i] - lastdel-1;
lastdel = &data[i];
if(*lastdel >(unsigned char) 254 )printf(" %c <++++~~~++++++++#######-------\n", *lastdel);
continue;
}
}
}
int main(void)
{
//readFile("/root/20101202.174715.std");
unsigned long s=290;
printf("hex: %x ", s<<24);
printf(" %x ", s<<16);
printf(" %x ", s<<8);
printf(" %x \n", s);
//exit(1);
int length ;
//unsigned char *bytes =readFile("/root/20101202.174715.std");
unsigned char bytes[] =
"\x31\x02\x00\x00\x67\x10\x00\x00\x00\x53\x02\x1E\x31\x1C\x36\x33\x1E\x37\x34\x1C\x55\x1E\x38\x1C\x44\x45\x30\x30\x30\x4C\x53\x38\x30\x35\x38\x36\x2E\x4C\x55\x53\x1E\x35\x1C\x38\x2E\x1D\x1E\x32\x38\x1C\x30\x2E\x36\x32\x30\x30\x1E\x33\x30\x1C\x30\x2E\x35\x39\x30\x30\x1E\x32\x36\x1C\x31\x35\x3A\x30\x33\x3A\x30\x34\x03\x02\x1E\x31\x1C\x36\x33\x1E\x37\x34\x1C\x55\x1E\x38\x1C\x44\x45\x30\x30\x30\x53\x46\x44\x30\x5A\x32\x36\x2E\x4C\x55\x53\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x1E\x35\x1C\x38\x2E\x1D\x1E\x32\x38\x1C\x31\x30\x2E\x30\x35\x38\x30\x1E\x33\x30\x1C\x31\x30\x2E\x30\x32\x38\x30\x1E\x32\x36\x1C\x31\x35\x3A\x30\x33\x3A\x30\x34\x03\x02\x1E\x31\x1C\x36\x33\x1E\x37\x34\x1C\x55\x1E\x38\x1C\x45\x55\x52\x4E\x4F\x4B\x2E\x46\x58\x56\x57\x44\x1E\x35\x1C\x31\x30\x2E\x1D\x1E\x33\x30\x1C\x37\x2E\x39\x35\x37\x31\x1E\x32\x38\x1C\x37\x2E\x39\x36\x32\x36\x1E\x38\x30\x1C\x37\x2E\x39\x35\x39\x38\x35\x1E\x37\x35\x32\x1C\x5A\x4B\x42\x5A\x1E\x32\x38\x31\x1C\x31\x35\x3A\x30\x33\x3A\x30\x34\x1E\x32\x36\x1C\x31\x35\x3A\x30\x33\x3A\x30\x34\x1E\x36\x34\x1C\x2D\x30\x2E\x30\x33\x39\x32\x1E\x31\x36\x34\x1C\x2D\x2E\x34\x38\x39\x34\x03\x45\x49\x00\x00\x00\x68\x10\x00\x00\x00\x53\x02\x1E\x31\x1C\x36\x33\x1E\x37\x34\x1C\x55\x1E\x38\x1C\x44\x45\x30\x30\x30\x39\x37\x36\x39\x37\x36\x30\x2E\x4C\x55\x53\x1E\x35\x1C\x31\x2E\x1D\x1E\x32\x38\x1C\x31\x30\x30\x2E\x38\x39\x30\x30\x1E\x33\x30\x1C\x31\x30\x30\x2E\x30\x39\x30\x30\x1E\x32\x36\x1C\x31\x35\x3A\x30\x33\x3A\x30\x34\x03\x45"
;
/* Speicher fuer String mit 4294967296 Zeichen reservieren */
unsigned char *data;
if (( data = ( unsigned char *) malloc(1000000000 * sizeof(unsigned char))) == NULL)
{
printf( "Nicht genug Speicher, um den Puffer zu allokieren\n");
exit(1);
}
printf( "Speicher fuer String wurde reserviert!\n" );
int strsize =((sizeof(bytes)/sizeof(*bytes))-1);
int pos =0;
int loop=1;
while(bytes[pos+9]=='S')
{
printf("----------------------------\n");
printf("| LOOP %d, POSITION %d |\n", loop, pos);
printf("----------------------------\n\n");
printf("hex: %x ", bytes[pos+0]<<24);
printf(" %x ", bytes[pos+1]<<16);
printf(" %x ", bytes[pos+2]<<8);
printf(" %x \n", bytes[pos+3]);
unsigned long size= ntohl(bytes[pos+0]<<24| bytes[pos+1]<<16| bytes[pos+2]<<8| bytes[pos+3]);
printf("=> RECOGNIZED SIZE: %lu \n", size );
printf("\n");
int seq = ntohl(bytes[pos+4]<<24| bytes[pos+5]<<16| bytes[pos+6]<<8| bytes[pos+7]);
printf("seq number: %d \n", seq );
printf("compressed: %d \n", bytes[pos+8]);
printf("start in hex: %x, in char: %c \n", bytes[pos+9], bytes[pos+9] );
//printf("HeaderFieldIdentifier: %c %c %c \n", bytes[pos+10], bytes[pos+11], bytes[pos+12]);
printf("stop in hex: %x, in char: %c \n\n", bytes[pos+size+10], bytes[pos+size+10] );
/* Array kreieren das nur auf die komprimierten Daten zeigt */
unsigned char *ptr;
ptr = &bytes[pos+10]; // Position des 1. Bytes
bytes[pos+size+10]='\0'; // Ende des Strings festlegen
/* Jetzt entkomprimieren wir die Daten */
int ret=0;
unsigned long size_uncompress = size;//1000000000 * sizeof(unsigned char);
if( bytes[pos+8]=='\x01')
{
size_uncompress = 1000000000 * sizeof(unsigned char);
ret=uncompress(data, &size_uncompress, ptr, size);
data[size_uncompress]='\0';
}
else
data = ptr;
//data[size_uncompress]='\0';
printf("%d|%lu|%lu|%x|%x|%x|%x\n",ret,size,size_uncompress,ptr[0],ptr[1],bytes[pos+10],bytes[pos+11]);
printf("\n");
printf("----------------------------\n");
printf("| Message as String: |\n");
printf("----------------------------\n");
printf("%s\n", data);
int i =0;
printf("\n");
printf("----------------------------\n");
printf("| Message as hexadecimal |\n");
printf("----------------------------\n");
for (i=0;i<size_uncompress ;i++)
{
printf("%x ",data[i] );
}
printf("\n\n");
printf("----------------------------\n");
printf("| Edited message |\n");
printf("----------------------------\n");
process(data, size_uncompress);
for (i=0;i<size_uncompress ;i++)
{
printf("%x ",data[i] );
}
printf("\n");
pos+=(size+11);
loop++;
}
//free(data);
}
Output
Orig. message
02 01 31 02 36 33 02 37 34 01 55 01 38 10 44 45 30 30 30 4c 53 38 30 35 38 36 2e 4c 55 53 01 35 02 38 2e 1d 02 32 38 06 30 2e 36 32 30 30 02 33 30 06 30 2e 35 39 30 30 02 32 36 08 31 35 3a 30 33 3a 30 34 03 02 01 31 02 36 33 02 37 34 01 55 01 38 ff 44 45 30 30 30 53 46 44 30 5a 32 36 2e 4c 55 53 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 **01** 35 02 38 2e 1d 02 32 38 07 31 30 2e 30 35 38 30 02 33 30 07 31 30 2e 30 32 38 30 02 32 36 08 31 35 3a 30 33 3a 30 34 03 02 01 31 02 36 33 02 37 34 01 55 01 38 c 45 55 52 4e 4f 4b 2e 46 58 56 57 44 01 35 03 31 30 2e 1d 02 33 30 06 37 2e 39 35 37 31 02 32 38 06 37 2e 39 36 32 36 02 38 30 07 37 2e 39 35 39 38 35 03 37 35 32 4 5a 4b 42 5a 03 32 38 31 8 31 35 3a 30 33 3a 30 34 02 32 36 8 31 35 3a 30 33 3a 30 34 02 36 34 07 2d 30 2e 30 33 39 32 03 31 36 34 06 2d 2e 34 38 39 34 3
Replaced message
02 1E 31 1C 36 33 1E 37 34 1C 55 1E 38 1C 44 45 30 30 30 4C 53 38 30 35 38 36 2E 4C 55 53 1E 35 1C 38 2E 1D 1E 32 38 1C 30 2E 36 32 30 30 1E 33 30 1C 30 2E 35 39 30 30 1E 32 36 1C 31 35 3A 30 33 3A 30 34 03 02 1E 31 1C 36 33 1E 37 34 1C 55 1E 38 1C 44 45 30 30 30 53 46 44 30 5A 32 36 2E 4C 55 53 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 **1E** 35 1C 38 2E 1D 1E 32 38 1C 31 30 2E 30 35 38 30 1E 33 30 1C 31 30 2E 30 32 38 30 1E 32 36 1C 31 35 3A 30 33 3A 30 34 03 02 1E 31 1C 36 33 1E 37 34 1C 55 1E 38 1C 45 55 52 4E 4F 4B 2E 46 58 56 57 44 1E 35 1C 31 30 2E 1D 1E 33 30 1C 37 2E 39 35 37 31 1E 32 38 1C 37 2E 39 36 32 36 1E 38 30 1C 37 2E 39 35 39 38 35 1E 37 35 32 1C 5A 4B 42 5A 1E 32 38 31 1C 31 35 3A 30 33 3A 30 34 1E 32 36 1C 31 35 3A 30 33 3A 30 34 1E 36 34 1C 2D 30 2E 30 33 39 32 1E 31 36 34 1C 2D 2E 34 38 39 34 03 45 49 00 00 00 68 10 00 00 00 53 02 1E 31 1C 36 33 1E 37 34 1C 55 1E 38 1C 44 45 30 30 30 39 37 36 39 37 36 30 2E 4C 55 53 1E 35 1C 31 2E 1D 1E 32 38 1C 31 30 30 2E 38 39 30 30 1E 33 30 1C 31 30 30 2E 30 39 30 30 1E 32 36 1C 31 35 3A 30 33 3A 30 34
First you check if the not yet replaced previous separator (*lastdel) is 255, as it has not been replaced, not wonder the case never occurs. Then you replace *lastdel with 255, and after replacing you change value of lastdel pointer to the next position (not yet changed) and you check if that position was replaced and contains 255...
No wonder the case never occurs. Just put the test at the right place and it should work fine.

Resources