C -- file input reading issue - c

I'm reading in from a file emp and it was reading when the file (which is the last file below -- which worked) was structured as 10 records with a header (being skipped by the fseek() of 0 in the code). But when it reads in with the 3x10 format (which is the middle file below, which failed to read properly) with headers for each block of 3 -- that's failing. I'm not sure why the conditional just within the loop isn't catching and the 2nd conditional within the loop isn't printing everything marked with a 0 upfront.
int nDeleteSwitch;
char sSSN[10], sName[21];
float nSalary;
char nextIn[3];
printf("SSN NAME SALARY\n");
mioHashFile = fopen("emp", "r");
fscanf (mioHashFile,"%d",&mnOverFlowRecords);
fseek (mioHashFile, mnHeaderSize, 0); //Skip past the CRLF at end of overflow counter
//int numHeadRec = mnOverFlowRecords/3;
/* sequentially print all active records */
//for(int i=0;i<(numHeadRec+mnOverFlowRecords);i++)
for(int i=0;i<20+mnOverFlowRecords;i++)
{
if ((fscanf(mioHashFile,"%d",nextIn)== -1) || (fscanf(mioHashFile,"%d",nextIn)== 0) ||
(fscanf(mioHashFile,"%d",nextIn)== 1))
{
fscanf(mioHashFile,"%d%s%s%f",&nDeleteSwitch,sSSN,sName,&nSalary);
//printf("%d",nDeleteSwitch);
if (nDeleteSwitch==0)printf("%-11s%-21s%-10.2f\n",sSSN,sName,nSalary); // wtf why this isn't printing
else if (nDeleteSwitch == -1) printf("there's a -1 on row: %d",i);
}
else {continue;};
}
fclose(mioHashFile);
printf("Print Table Complete\n");
And here we have emp file that it's refusing to read the 0 entries from:
0
Overflow page: 0 0 -1
-1 x x 0.00
-1 x x 0.00
0 x x 0.00
Overflow page: 1 0 -1
-1 x x 0.00
-1 x x 0.00
0 x x 0.00
Overflow page: 2 0 -1
-1 x x 0.00
-1 x x 0.00
-1 x x 0.00
Overflow page: 3 0 -1
-1 x x 0.00
-1 x x 0.00
-1 x x 0.00
Overflow page: 4 0 -1
-1 x x 0.00
-1 x x 0.00
-1 x x 0.00
Overflow page: 5 0 -1
-1 x x 0.00
-1 x x 0.00
-1 x x 0.00
Overflow page: 6 0 -1
-1 x x 0.00
-1 x x 0.00
-1 x x 0.00
Overflow page: 7 0 -1
-1 x x 0.00
-1 x x 0.00
-1 x x 0.00
Overflow page: 8 0 -1
-1 x x 0.00
-1 x x 0.00
-1 x x 0.00
Overflow page: 9 0 -1
-1 x x 0.00
-1 x x 0.00
-1 x x 0.00
So it won't read that, but it'll read this:
0
0 123 asd 789.00
-1 x x 0.00
-1 x x 0.00
-1 x x 0.00
-1 x x 0.00
-1 x x 0.00
0 345 zxc 234.00
-1 x x 0.00
-1 x x 0.00
-1 x x 0.00
There's a space right before the -1 and there'd be 2 spaces before the 0. As shown in the code, I'm trying to print anything with a 0 at the beginning, and skip over the 'header' lines at the front of each hash block. When I try to force it to print (like print < 3) then it just comes out as garbage symbols.
What it should be doing is printing all records that have a 0 at the beginning and skipping over the headers (because they don't have -1,0,1 at the beginning).

Given the declaration:
char nextIn[3];
This code is wrong:
if ((fscanf(mioHashFile,"%d",nextIn) == -1) || (fscanf(mioHashFile,"%d",nextIn) == 0) ||
(fscanf(mioHashFile,"%d",nextIn) == 1))
{
You are passing an array of three characters and expecting fscanf() to treat it as an int. Your conditions are odd, too. EOF is not guaranteed to be -1 (though I don't recall a system where it was not). There wouldn't be much point in trying again after detecting EOF (not without other activity to clear the EOF marker).
When I try this fscanf(mioHashFile,"%s",nextIn); if (strcmp(nextIn, '-1') == 0) it still crashes and burns opulently due to type incompatibility. #Emmet also caught my error on the EOF (in that answer's code). How would you do it, and still maintain the scanf(), printf() formatting that I'm trying to use?
That requires some semi-real coding. I'd use fgets() and sscanf() rather than fscanf():
char line[4096];
int lineno = 0;
while (fgets(line, sizeof(line), mioHashFile) != 0)
{
if (++lineno == 1)
continue; // Skip the offset line
if (line[0] == 'O') // Overflow line - skip
continue;
if (sscanf(line, "%d %9s %20s %f", &nDeleteSwitch, sSSN, sName, &nSalary) != 4)
{
fprintf(stderr, "Failed to scan data from: %s", line);
continue;
}
if (nDeleteSwitch == 0)
printf("%-11s%-21s%-10.2f\n", sSSN, sName, nSalary);
else if (nDeleteSwitch == -1)
printf("there's a -1 on row: %d\n", lineno);
else
printf("The delete switch value is %d\n", nDeleteSwitch);
}
Note that %s skips leading white space and then stops scanning at the next white space.

Almost all of the detail you supply seems irrelevant to your stated objective of printing out lines that begin with a zero and not printing out the others. The following program, for example, prints out all of the lines that begin with a zero, but no others.
#include <stdio.h>
#include <stdlib.h>
#define BUF_SZ (512)
#define INFILE "datafile.txt"
int main(void) {
char buf[BUF_SZ] = {0};
FILE *fp;
long first;
char *endp;
/* Open input file successfully or bail */
fp = fopen(INFILE, "r");
if( fp == NULL ) {
fprintf(stderr, "Failed to open '%s'\n", INFILE);
exit(EXIT_FAILURE);
}
/* Read each line, convert beginning to long and print if it's 0 */
while( NULL!=fgets(buf, BUF_SZ, fp) && !feof(fp) ) {
first = strtol(buf, &endp, 10);
if( first==0L && endp!=buf ) {
fputs(buf, stdout);
}
}
fclose(fp);
return 0;
}

Related

Reading the contents of a file into a buffer in C

I'm working on a program which reads every integer in csv file and copies it into a buffer so that I can later use it to construct a binary search tree with it. I'll show my code, then I'll explain the issue I'm having:
Code -
int *createBuffer(int count) {
FILE *file = fopen(FILE1, "r");
int buffer[count + 1];
int *bufferPointer = buffer;
int number;
int ch;
int i = 0;
while (1) {
ch = fgetc(file);
if(ch == EOF){
break;
}
if (fscanf(file, "%i", &number)) {
buffer[i] = number;
i++;
}
}
return bufferPointer;
}
Count refers to the number of commas that are present in the file so I can allocate enough space for each number in the array. The file pointer points to the file I'm opening in read-only mode. The buffer is created using the aforementioned count variable. bufferPointer is the pointer to the buffer that I'm returning from the function. The while loop runs until the variable ch is equal to EOF at which point it breaks. The if statement's purpose is basically to scan the file for integers and read them into number, and then copy number into the next buffer index. Finally, the buffer pointer is returned.
This code is giving me extremely strange results. When I print the buffer, I get the result:
9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 850045856 0 -2141008008 32767 0 0 214814639 1 0 0 -2141007448 32767 0 0 214814639 1 -487430544 32766 539243238 32767 -2141007448 32767 6 0 -487430496 32766 539279361 32767 0 0 0 0 0 0 0 0 -487430272 32766 539271526 32767 92 68 68 0 0 0 69 0 -2141007976 32767 0 0 42 68 55 46 10 40 44 100 75 63 19 13 10 95 43 47 47 49 59 40 0 0 -2141006600 %
The reason this is strange is because although I am getting some garbage values, the entire sequence from 42...40 matches numbers in my data file. I'm not exactly sure where I'm going wrong in this code so if anyone knows, please do share.
As always, if you take the time to answer or attempt to answer this question, thank you for your time. If you need further clarification, don't hesitate to ask.
This is a "fixed" version of your code. But you will notice that it does not print the first character. Lets say, if the first number in your file is, 220, then it will print 20.
The reason is - your program first takes away a character from file in c=fgetc(file). So at first iteration, it takes away the first character 2 from 220 and then stores 20 in the memory. Thought this problem does not occur for the rest of the iterations because the first character is comma in those cases.
To go around that problem, we can just put c=getc(file) at the end of the loop. This way, after entering the loop, it reads the first number, gets rid of the comma, reads next number, gets rid of the comma....
#include<stdio.h>
#include<stdlib.h>
int *createBuffer(int count) {
FILE *file = fopen("filename.txt", "r");
int* buffer = (int*)malloc(sizeof(int)*(count + 1));
int number;
int ch;
int i = 0;
while (1) {
if (fscanf(file, "%i", &number)) {
buffer[i] = number;
i++;
}
ch = fgetc(file);
if(ch == EOF){
break;
}
}
return buffer;
}
void main(){
int* arr = createBuffer(10);
for(int i=0; i<10; i++){
printf("%d ",arr[i]);
}
printf("\n");
}

How to read a file, convert letters, and print string and integers to an array in c?

struct reviewStruct {
char reviewer[50];
int feedback[3];
};
int readReviews(FILE *file, struct reviewStruct reviews[10]) {
int i;
file = fopen("Names.txt", "r");
if(file == NULL) {
printf("Error");
exit(-1);
}
for(i = 0; i < 10; i++) {
fgets(reviews[i].reviewer, 50, file);
}
fclose(file);
for(i = 0; i < 10; i++) {
printf("%s", reviews[i].reviewer);
}
return 0;
}
Hello, I'm trying to read a file line by line and print it to an array, with a catch. Whenever a 'Y' or 'y' appears, it converts that letter into a 1, and if an 'N' or 'n' appears, it is converted into a 0 (zero), excluding the first word of every line. For example, I have a file with the following information:
charlie Y n N
priya N n Y
lance y y Y
stan N y n
arin N n N
This is the text file called Names.txt, I want to save the integer information to the array called "feedback", so that it looks like this when printed using a for loop:
1 0 0
0 0 1
1 1 1
0 1 0
0 0 0
How do I populate the feedback array such that it can be printed along with the names using a for loop as it is in the following image?
charlie 1 0 0
priya 0 0 1
lance 1 1 1
stan 0 1 0
arin 0 0 0
Thanks.

Updating a matrix with special cases

I am trying to write a function which gets a matrix 9x9 and updates it accordingly to user's input with the following rules:
Valid number is between 1 and 9 (zero is invalid).
I have to use scanf until I get EOF.
Input has digits and symbols. valid input is a pair of two digits following with a symbol or EOF or space. string with more than two digits is invalid. for example (123% isn't valid but 12% is valid).
Example:
Input: 10 33%55^21 $123%
Output:
0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
Explanation: 10 and 123 are invalid. 33, 55 and 21 are valid so we will put 1 in 22, 44 and 10.
What I tried to do:
void updateMarix(int matrix[][9]) {
int digits = 0, one_previous, two_previous;
char input;
while (scanf("%c", &input) != EOF) {
if(isValidDigit(input)) {
digits++;
if(digits == 1) {
two_previous = input - '0' - 1;
continue;
} else if(digits == 2){
one_previous = input - '0' -1;
continue;
}
} else if(digits == 2) {
matrix[two_previous][one_previous]++;
}
digits = 0; // reset
}
}
most tests are end with success, but some of them are fail. I think that is because I don't handle with the last input (if for example it ends with 22 it won't update it because with my implementation, the update is in the next iteration when other symbol got as input).
Is there a better implementation for this? My code became messy and not clean.
*Edit: It should ignore invalid input and a3b doesn't counts, a03b also doesn't counts but a13b does counts as 13 meaning we should increase the number in matrix[0][2].
Edit 2: #JonathanLeffler menationed FSM so I tried to create one:
Although it doesn't handles the case of 1234 (invalid number) or 123 (also invalid). The most similar thing was to create an arrow from second number to symbol (but it isn't quite true because in 1234%12 only 12 is valid.
I think your FSM needs 4 states plus the end state:
Zero digits read (D0).
One digit read (D1).
Two digits read (D2).
Digits are invalid but no more error reporting needed (DI).
There are 4 different inputs, too:
Digit 1-9.
Digit 0.
Other.
EOF.
I've used a switch on state and if/else code in each state, but it leads to somewhat verbose code. OTOH, I believe it handles inputs correctly.
/*
** FSM
** States: 0 digits (D0), 1 digit (D1), 2 digits (D2), digits invalid (DI)
** Inputs: digit 1-9 (D), digit 0 (0), other (O), EOF.
** Action: S - save, E - error, I - ignore, P - print
** Body of FSM encodes "action;state"
**
** State D0 D1 D2 DI
** Input
** D S;D1 S;D2 E;D2 I;DI
** O I;D0 E;D0 P;D0 I;D0
** 0 E;D2 E;D2 E;D2 I;DI
** EOF I;end E;end P;end I;end
*/
#include <assert.h>
#include <ctype.h>
#include <stdio.h>
enum State { D0, D1, D2, DI };
enum Input { Digit, Zero, Other, End };
static int debug = 0;
static enum Input input(int *rv)
{
int c = getchar();
if (debug)
printf("Input: %c\n", (c == EOF) ? 'X' : c);
*rv = c;
if (c == EOF)
return End;
if (isdigit(c))
{
*rv = c - '0';
return (c == '0') ? Zero : Digit;
}
return Other;
}
static void updateMatrix(int matrix[9][9])
{
char pair[2] = { 0, 0 };
enum State state = D0;
int c;
enum Input value;
while ((value = input(&c)) != End)
{
switch (state)
{
case D0:
if (value == Digit)
{
pair[0] = c;
state = D1;
}
else if (value == Zero)
{
fprintf(stderr, "Received zero digit - invalid\n");
state = DI;
}
else
{
assert(value == Other);
}
break;
case D1:
if (value == Digit)
{
pair[1] = c;
state = D2;
}
else if (value == Zero)
{
fprintf(stderr, "Received zero digit - invalid\n");
state = DI;
}
else
{
assert(value == Other);
fprintf(stderr, "Received one digit where two expected\n");
state = D0;
}
break;
case D2:
if (value == Digit)
{
fprintf(stderr, "Received more than two digits where two were expected\n");
state = DI;
}
else if (value == Zero)
{
fprintf(stderr, "Received zero digit - invalid\n");
state = DI;
}
else
{
assert(value == Other);
printf("Valid number %d%d\n", pair[0], pair[1]);
matrix[pair[0]-1][pair[1]-1] = 1;
state = D0;
}
break;
case DI:
if (value == Other)
state = D0;
break;
}
}
if (state == D2)
{
printf("Valid number %d%d\n", pair[0], pair[1]);
matrix[pair[0]-1][pair[1]-1] = 1;
}
else if (state == D1)
fprintf(stderr, "Received one digit where two expected\n");
}
static void dump_matrix(const char *tag, int matrix[9][9])
{
printf("%s:\n", tag);
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
printf("%4d", matrix[i][j]);
putchar('\n');
}
}
int main(void)
{
int matrix[9][9] = { 0 };
updateMatrix(matrix);
dump_matrix("After input", matrix);
return 0;
}
On your test input, it produces the output:
Received zero digit - invalid
Valid number 33
Valid number 55
Valid number 21
Received more than two digits where two were expected
After input:
0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
On the mostly-invalid input file:
123345132
bbbb12cccc1dddd011dd
it produces the output:
Received more than two digits where two were expected
Valid number 12
Received one digit where two expected
Received zero digit - invalid
After input:
0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
You can argue (easily) that the error messages could be more informative (identifying the erroneous character, and possibly the prior valid digits), but it only produces one error message for each invalid sequence, which is beneficial.
You could use a combination of fgets(), sscanf() and strpbrk() for this.
The input line is read into a character array str and a pointer ptr pointing to the part of the string in str being processed is maintained.
First, set up a loop to read input line by line. fgets() will return NULL on EOF.
for(; fgets(str, sizeof(str), stdin); )
{
...
...
...
}
fgets() will read in the trailing newline as well. You could remove it like
str[strlen(str)-1]='\0';
Now inside the above loop, use another loop to process the input line in str like
for(ptr=str; (ptr=strpbrk(ptr, "0123456789"))!=NULL; ptr+=len)
{
sscanf(ptr, "%d%n", &n, &len);
if(n>10 && n<100)
{
//accepted
printf("\n%d", n);
arr[n/10][n%10]=1;
}
//else discarded
}
strpbrk()'s prototype is
char *strpbrk(const char *s1, const char *s2);
and it returns a pointer to the first character in s1 which is a character in the string s2. If there is no match, NULL is returned.
So we are looking to see the first digit part in str that remains to be processed with strpbrk(ptr, "0123456789").
This number part is read into n via sscanf(). If this number is in the range you need, you may accept it.
The %n format specifier is used to find out the number of characters which has been scanned with the sscanf() inorder to find the value by which ptr must be updated. See this post.
The digit in the ones place will be n%10 and that in the tens place will be n/10 as the number you need is a 2-digit number.
You may set your array representing the matrix like
arr[n/10][n%10]=1;
So the whole thing could look something like
char *ptr, str[50];
for(; fgets(str, sizeof(str), stdin); )
{
for(ptr=str, str[strlen(str)-1]=0; (ptr=strpbrk(ptr, "0123456789"))!=NULL; ptr+=len)
{
sscanf(ptr, "%d%n", &n, &len);
if(n>10 && n<100)
{
printf("\n%d", n);
arr[n/10][n%10]=1;
}
}
}
And for your input 10 33%55^21 $123%, the output would be
33
55
21
as 10 and 123 will be discarded.

Scanf with optional text

I'm trying to read a .txt file, which contains a name and a last name in the first line and below contains an array
The problem is that the first line may or may not one letter A in brackets like this: [A].
for instance:
Jose Perez [A] or may have jose perez
When I run here mentioned code, if the first line does not contain a [A] performs a shift of values, for example the value of the matrix [1] [1] is up as tester and insert a 0 at the end to complete the matrix.
Here is a sample of what gives the code when there is a [A] in the first line and when not
FILE* text=NULL;
text=fopen(archivo,"r");
char name[100];
char last_name [100];
char verifier [10];
int matriz[6][4];
int i ;
int lu,ma,mi,ju,vi;
if (text == NULL) {
}
else {
fscanf(text,"%s %s %s [^\n]",name, last_name, verifier);
for( i= 0; i<7;i++){
fscanf(text,"%d %d %d %d %d [^\n]",&lu, &ma, &mi,&ju,&vi);
matriz[i][0] = lu;
matriz[i][1] = ma;
matriz[i][2] = mi;
matriz[i][3] = ju;
matriz[i][4] = vi;
}
Result:
Jose Perez 1
0 0 0 0 0
1 0 1 0 1
0 1 1 1 1
0 1 1 0 0
1 0 0 0 0
1 1 1 0 0
1 0 1 0 0
Juan Perez A
1 0 1 1 1
0 0 1 1 1
0 0 1 0 1
0 0 1 1 1
1 0 1 0 1
0 0 1 1 1
0 1 1 1 0
As could be solved?
char line[80], fname[16], lname[16], third[4];
fgets(line, 80, fp)
if (sscanf(line, "%s %s %s\n",
fname, lname, third) == 3 && strcmp(third, "[A]") == 0)
// the line has a [A] at the end
else if (sscanf(line, "%s %s\n", fname, lname) == 2)
// the line does not have a [A] at the end
else
fprintf(stderr, "Invalid line");
fgets reads the next line from the file. If it is not null, we check the return value of sscanf. It returns the number of items parsed. So, on success it should return 3. If it contains a [A] at the end of the line, the third variable should compare equal to [A].
After all this, we can proceed to read the array.
Since your verifier is always a single character, you can let scanf do the work. In the example below it will stop scanning if the opening bracket does not exist, but get the verifier character otherwise:
char name[100];
char last_name [100];
char verifier = 0;
int n = fscanf("%s %s [%c]", name, last_name, &verifier);
If n == 2 there was no verifier, if n == 3 there was a verifier, and in any other case, there was an error.

walsh table for nxn matrix in C

I have been trying to understand the walsh table matrix for n-dimension since I am required to write a code that generates the walsh matrix for any given order. I have so far failed to write a working code. Can anyone help me with the algorithm, or suggest something about my program below:(it works for 2x2 and 4x4 but fails for 8x8)
#include<stdio.h>
#include<conio.h>
main()
{
/* Program variables
Dimension variable, n
Loop variables i,j
Two dimensional array for walsh table a[100][100] */
int n,j,i,a[100][100];
clrscr();
// User input to display walsh table
printf("enter the size ");
scanf("%d",&n);
// Iterate rows from 0 to 'n'
for(i=0;i<n;i++)
{
// Iterate columns from 0 to 'n' for each row 'i'
for(j=0;j<n;j++)
{
if(i%2==1 && j%2==1) // for both i & j not divisible by 2, initialize array elements with -1
a[i][j] = -1;
else if(i/2==1 && j/2==1){ // for both i & j, if completely divisble by 2 and dividend is 1
if(j == 3 && i == 3){
a[i][j]=1;
}
else
a[i][j] = -1;
}
else
a[i][j] = 1; // default case initialized to 1
}
a[3][3] = 1;
}
// Output complete walsh table
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("\t%d",a[i][j]);
}
// go to next line after every row
printf("\n");
}
getch();
}
You should be looking at the generation of a Walsh code as a recursive problem. First you generate the 2x2; from that you generate the 4x4, etc. Each time, the next block is generated from the previous one by adding two copies of the lesser-order block in the top-right and bottom-left quadrant, and its inverse in the bottom right hand quadrant. You can do this by creating the matrix once, and working your way through it in increasing block sizes. Here is how that works
UPDATED so it produces the 1 -1 version of the code that you saw on wiki;
UPDATED AGAIN to make it capable of taking an input for the size of the matrix and generate a Walsh matrix of arbitrary size; includes all kinds of error checking and other cool tricks:
FINAL(?) UPDATE Ryyker pointed out that there was a memory error in my code. I found and fixed it - and checked it with valgrind to be sure. It seems to be working fine now.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int **twoDmatrix(int m, int n) {
// create a 2D matrix of arbitrary dimensions
int ii, **M;
M = malloc(m * sizeof(int**));
M[0] = malloc(m*n*sizeof(int*));
for(ii=1; ii<m; ii++) {
M[ii] = M[0] + ii * n;
}
return M;
}
void free2D(int** M) {
// free memory allocated by twoDmatrix()
free(M[0]);
free(M);
}
int isPow2(int n) {
// return 1 if the argument is a valid (positive) power of 2
if(n<=1) return 0;
while(n>1) {
if (n%2==1) return 0;
n = n/2;
}
return 1;
}
void emptyBuf(void) {
while(getchar()!='\n');
return;
}
int main(void) {
int **W;
int N;
int power = 1;
int i,j,k,l,p=0;
while(1==1) {
printf("enter the size of the matrix - must be a positive power of 2\n");
if(scanf("%d", &N)!=1) {
printf("unable to scan input\n");
emptyBuf();
continue;
}
if (!isPow2(N)) {
printf("%d is not a valid power of 2\n", N);
continue;
}
break; // valid input: go on
}
W = twoDmatrix(N,N); // allocate memory for 2D matrix
W[0][0]=1; // this is the 1x1 Walsh code...
while (power < N) {
for(i=0; i<2; i++) {
for(j=0; j<2; j++) {
if (!(i==0 && j==0)) {
for(k=0; k<power; k++) {
for(l=0; l<power; l++) {
if (i==1 && j == 1) {
W[i*power+k][j*power+l] = -W[k][l]; // invert signal
}
else {
W[i*power+k][j*power+l] = W[k][l]; // copy signal
}
}
}
}
}
}
power *=2; // double matrix and repeat
}
// print out result
for(i=0; i<N; i++) {
for(j=0; j<N; j++) {
printf("%2d ", W[i][j]); // <<<<< updated
}
printf("\n");
}
free2D(W); // always remember to free your memory...
}
output:
enter the size of the matrix - must be a positive power of 2
5
5 is not a valid power of 2
enter the size of the matrix - must be a positive power of 2
3
3 is not a valid power of 2
enter the size of the matrix - must be a positive power of 2
0
0 is not a valid power of 2
enter the size of the matrix - must be a positive power of 2
-4
-4 is not a valid power of 2
enter the size of the matrix - must be a positive power of 2
asdf
unable to scan input
enter the size of the matrix - must be a positive power of 2
asdfasdfasdfasdf
unable to scan input
enter the size of the matrix - must be a positive power of 2
16
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1
1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1
1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1
1 1 1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1
1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1
1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 1 1
1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1
1 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1
1 -1 1 -1 1 -1 1 -1 -1 1 -1 1 -1 1 -1 1
1 1 -1 -1 1 1 -1 -1 -1 -1 1 1 -1 -1 1 1
1 -1 -1 1 1 -1 -1 1 -1 1 1 -1 -1 1 1 -1
1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1
1 -1 1 -1 -1 1 -1 1 -1 1 -1 1 1 -1 1 -1
1 1 -1 -1 -1 -1 1 1 -1 -1 1 1 1 1 -1 -1
1 -1 -1 1 -1 1 1 -1 -1 1 1 -1 1 -1 -1 1
For reference see http://my.fit.edu/~kostanic/Personal%20Communication%20Systems/ECE%205221%20-%20Lecture14.pptx - from which I took the following:
POSTSCRIPT
A note about the twoDmatrix() function. I wrote this function because there is no direct way to allocate a 2D matrix of unknown size in C. So this function creates an array of pointers to int - one pointer for each row in the matrix; and it also allocates a block of memory - one for each element in the array. It then associates one pointer with the start of each row in the matrix, so that you can access the elements with the usual W[i][j] indexing. This makes it look like the first row of the array is really long (it points to the entire NxN block), the second row is a little shorter, etc. But it's just a trick so you can access the elements of the array with the usual syntax. Imagine that you have a 3x3 array filled with the numbers 0 to 8 - then things look like this:
pointer values
W[0] 0 1 2
W[1] 3 4 5
W[2] 6 7 8
But another way of looking at it is this:
0 1 2 3 4 5 6 7 8
^ W[0]
^W[1]
^W[2]
What this means is that you could access the element W[0][6] - its value would be the same as W[1][3] which again is the same as W[2][0].
When you no longer need the function, you have to free the two blocks of memory - first the data block, and then the pointer block. This is the role of the free2D() function.
Modified Your code: There are three things I did:
1) formatted with more blocks {...} for readability
2) initialized array a[100][100] for all elements using memset()
3) added an extra getchar() (my system uses that instead of getch() ), and commented clrscr()
It ran for 4x4 and 8x8 (but the output does not look correct, you have more work to do there):
main()
{
/* Program variables
Dimension variable, n
Loop variables i,j
Two dimensional array for walsh table a[100][100] */
int n,j,i,a[100][100];
//clrscr();
// User input to display walsh table
memset(a, 0, 100*100);
printf("enter the size ");
scanf("%d",&n);
// Iterate rows from 0 to 'n'
for(i=0;i<n;i++)
{
// Iterate columns from 0 to 'n' for each row 'i'
for(j=0;j<n;j++)
{
if(i%2==1 && j%2==1) // for both i & j not divisible by 2, initialize array elements with -1
{
a[i][j] = -1;
}
else if(i/2==1 && j/2==1)
{ // for both i & j, if completely divisble by 2 and dividend is 1
if(j == 3 && i == 3)
{
a[i][j]=1;
}
}
else
{
a[i][j] = -1;
}
}
a[i][j] = 1; // default case initialized to 1
}
a[3][3] = 1;
// Output complete walsh table
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("\t%d",a[i][j]);
}
// go to next line after every row
printf("\n");
}
getchar();
getchar();
}

Resources