Adak 419 Nearly a Posting Virtuoso

Your code will stay formatted properly, only if you click on the [CODE ] icon in the editing window, and paste your code right between the code tags that the editor gives you:

[CODE ]
<YOUR CODE GOES HERE>
[/CODE ]

Take a look at this. I couldn't quite grasp the logic that was involved in your program.

#include<stdio.h>

#define p printf
#define s scanf

int main()
{
  int totalDays,day,i, j, r, c, firstDay;

  //clrscr();
  printf("\n\n\n");
  p("Input Number of days in a month:");
  s("%d",&totalDays);
  p("Input the first day of the month:");
  s("%d",&firstDay);

  p(" Sun  Mon  Tues  Wed  Thurs  Fri  Sat\n");

  for(r=0,day=0;r<5;r++)
  {
    if(r==0) {     //printing the first row only
      for(j=0;j<7;j++) {
        if(j==2 || j==4 || j==5) //handles days with 4 letters, etc.
          putchar(' ');          //I don't like using tabs
        if(j<firstDay) 
          printf("     ");      //as you can tell ;)
        else
          printf(" %2d  ", ++day);
      }
      putchar('\n');
    }
    for(c=0;c<7;c++) {    //prints all the other rows
      if(++day>totalDays)
        break;
      if(c==2||c==4 ||c==5)
        putchar(' ');     //about the same as the first row
      printf(" %2d  ", day); 
    }
    printf("\n");          
  } 
  getch();
  return 0;
} 
Adak 419 Nearly a Posting Virtuoso

This is the C forum. Do you believe that we don't deal with C problems? ;)

One look around the place should have enlightened you on that point. Post your code, and describe what the problem is - tell us what it is that has you stumped.

Adak 419 Nearly a Posting Virtuoso
if((strcmp(string1, string2))==0) 
  string1 is equal to string2

or

int num = strcmp(string1, string2);
if(num==0) 
  strings are equal
else if(num < 1)
  string2 is greater than string1 //note the direction of 
   //the < (big "mouth", facing string2)
else
  string1 is greater than string 2 //string1 now has the "big mouth" of the > symbol
Caeon commented: Detailed and helpful +1
Adak 419 Nearly a Posting Virtuoso

When will tokens == NULL? It's the name of an array, it's not the contents of the any element of the array.

Adak 419 Nearly a Posting Virtuoso

It looks like you're doing this in the upper code:

j=((pow(rad,i))/q;

but doing this in the lower code:

j=(pow(rad,i)/q);

I'm not sure if they're equivalent, or not.

That was a common punishment for an architect's failure, in the Ancient world. Kept the guys on their toes. ;)

Adak 419 Nearly a Posting Virtuoso

How would YOU find the lowest price item?

Perhaps, in a loop, you'd compare each item, and if it was the lowest priced item so far, set that value to be the lowPrice varible's value?

Adak 419 Nearly a Posting Virtuoso

What is the range of shorts on your system? My old compiler has a SHRT_MAX in the header file <limits.h>, that won't go to 360.

If you make a habit of using the absolute minimal data type for your variables, you WILL get bitten by the "overflow" bug, a great deal. Engineers never build a structure to withstand a certain stress - it's always a certain stress PLUS a safety margin.

I think they started doing that about the time that architects/builders were killed if their buildings collapsed. ;)

Adak 419 Nearly a Posting Virtuoso

Yes, malloc() returns NULL if the allocation failed. Did you include stdlib.h? Your cast of the pointer from malloc, is unnecessary in C, and will prevent the compiler from issuing an error regarding this oversight with stdlib.h.

I don't believe 1000 char's is too much, but check the other variable values to ensure that the buffer is not being freed, etc.

You want to check the pointer address at 307, not at 306, in your debugger. It will still be NULL until AFTER malloc returns the proper address, at the end of line 306, not at the start.

Adak 419 Nearly a Posting Virtuoso

Strings in C are compared, using the include file string.h, and the strcmp() function. Here's how it works:

The value returned by strcmp() tells whether the strings are:

0: means they are equal
>0: means string1 is > than string2
<0: means string1 is < string2

int variable = strcmp(string1, string2);

or

if((strcmp(string1, string2)) > 0) {
   //string1 was > string2 (see how the >'s match up)
}

BTW, example 9 is going to be at the top of your list, if it's sorted in descending order.

Do you have some sorting code? If not, post up your code, and let's get you sorting. ;)

Adak 419 Nearly a Posting Virtuoso

Your problem is an example of an "exact cover" problem. Google that and read up. Any references to "DLX" or "Dancing Links" or "Algorithm X" typically noting Knuth, you are wise to skip - that is a very complex algorithm.

Think of your L shaped "tiles". Nevermind the blank square for now. Turned in one way, two L tiles, form a very nice rectangle of 2 X 3 squares. Each such square has a length and a width, and your big square has a length and a width, and I'll bet money that if you find a configuration where the length and width of the small tiles, are integers that are factors of the big tiles length and width, that you'd have it solved.

Don't forget to "break a tile" to put the blank square into it. (like the 3 sqr in your example)

Adak 419 Nearly a Posting Virtuoso

There is no string in your program, at all. A bunch of letters are not a string, in C. They must have an end of string char, to mark the end of the string: '\0'. Only then are letters, elevated up to string status.

A single char can never be a string. It must have at least one char, AND the end of string char (which you can not see on the screen, normally. Use your debugger to see it).

Adak 419 Nearly a Posting Virtuoso

I don't mean to be harsh, but it looks like you're doing the same thing as last week. It's time to put that shovel away, and quit digging a deeper hole, isn't it?

You have a notion that you can do this, a certain way, and clearly, you can't. I can't quite wrap my head around what it is exactly that you're trying to do, but at some point it will become evident, that you need to step back, and use a different approach.

This is the Borland help file and example, from Turbo C/C++. This is as basic and clear as it gets, I believe:

malloc Allocates memory.


Syntax:
void *malloc(size_t size);

Prototype in:
alloc.h stdlib.h

Remarks:
malloc allocates a block of size bytes from
the memory heap. It allows a program to
allocate memory explicitly as it's needed, and
in the exact amounts needed.

The heap is used for dynamic allocation of
variable-sized blocks of memory. Many data
structures, such as trees and lists, naturally
employ heap memory allocation.

All the space between the end of the data
segment and the top of the program stack is
available for use in the small data models,
except for a small margin immediately before
the top of the stack.

This margin is intended to allow the
application some room to make the stack
larger, in addition to a small amount …

Adak 419 Nearly a Posting Virtuoso

What is the program solving?

With the current logic, start with i, and see if you can narrow the range, a bit. Then repeat with j, and k.

And what about N? Can it be brought down any?

You should get a boost by redoing your arrays down to all one dimension arrays. You can lose as much in clarity as you gain in faster run-time, however.

Narrowing the range has to be emphatically emphasized. (Lovely alliteration!) ;)

Adak 419 Nearly a Posting Virtuoso

You have to first set up your design for the histogram.

What is the range of the historgram (lowest and highest).

Just four students will be shown in it?

What will each star represent, as a number or letter? What grade or score gets what number of stars?

char gr[50][4], might be OK, depending on your answers to the above questions.

Adak 419 Nearly a Posting Virtuoso

Imo, it's best to make a 2D array (static) for your data. That is your histograms, which you will fill in, before you print it.

The code is a bit longer, but I like it because you can view one row of the array, as it's being made up, and ensure it's accurate.

In your case, A would be on the zero'th row, and F would be on the highest row.

What is your question or problem?

Adak 419 Nearly a Posting Virtuoso

I don't understand what you're doing with the variable n?

You don't want all the numbers going into the array temp[]?

Adak 419 Nearly a Posting Virtuoso

When someone takes the time to test and find a bug in your program, it seems the least you could do when posting a revised version, is to point out:

1) Whether the bug is now fixed, and

2) What the new testing you did, reveals for the limits of the program.


This is NOT a criticism of this program, since this is a general student type algorithm,

*BUT*

Looking at the problem, it might seem that we need to test every odd number, from the square root of the number, right on down to a very low number (say, 3).

But do we??

Wait a dang minute! Because every compound number (the non-prime numbers), are factors of prime numbers - so ONLY the prime numbers from the square root of the number being tested, down to 3, need to be tested!.

Aha! ;)

This change in the algorithm won't help in finding any of the lower prime numbers, (because of the added overhead), but definitely it will help, when the numbers being checked, get really large.

Adak 419 Nearly a Posting Virtuoso

char string[50][50];

and use atoi() to convert a char string of digits, to an int. "alphanumberic to int", see?

clever, no? ;)

Adak 419 Nearly a Posting Virtuoso

Dude, you don't need to "open" argv - it's there, just waiting for you, courtesy of the C compiler.

C automatically opens stdin, stdout, stderr, and creates argc and argv, when your program starts. (May not be an exhaustive list)

Adak 419 Nearly a Posting Virtuoso

Ninja-posted - blah! ;)

Adak 419 Nearly a Posting Virtuoso

Welcome to the forum, Hussamat! ;)

Now you trouble shoot it:

1) crate a list with 5 nodes and give them 1, 10, 20, 30, 40, values.

2) now try to add three values, working one at a time, until you know it's working correctly:

0:

25:

55:

So you cover adding to the list before the current first node, adding to the middle, and adding to the very end of the list.

Work through adding 0 to the list, noting the ADDRESSES of the nodes, and what your program is doing with them, as you step through your program.

When that's working, repeat with 25 and 55.

Trouble shooting is a very important skill for programming, and it takes practice. A simple problem like this is the PERFECT time to help develop that skill, and you will learn to be a better programmer, as well.

Adak 419 Nearly a Posting Virtuoso

Welcome to the forum, MK1985! ;)

You REALLY think we can diagnose the problem, without seeing the relevant code?

<< ha ha ha ha ha ha that's hilarious! ha ha ha ha ha ha ha >>

Adak 419 Nearly a Posting Virtuoso

Strings are not compared with the == sign in C. Use strcmp(). When it returns 0, then the strings are equal.

Adak 419 Nearly a Posting Virtuoso

I don't know what you mean by "aging in operating system".

If you want helpful answers, you need to be a lot more specific about the problem, and how you want to solve it, etc.

Posting some or all of your code, and giving examples of input and desired output, can only be helpful.

Adak 419 Nearly a Posting Virtuoso

log n is just that: log n.

n log n is: n(log n)

Line 23 should stay. I don't know what "global" does.

You have code for a merge sort, labeled as binary sort!

Adak 419 Nearly a Posting Virtuoso

You've replied to a thread that is 4 years old. I doubt the OP is still expecting an answer and will read your post.

Start a new thread for your top, so it will get noticed, and get some answers. A comparison is made whenever you compare the value of one number in the array, with the value of another number in the array.

Can't really say it any clearer than that. ;)

Adak 419 Nearly a Posting Virtuoso

Checked on the big O (efficiency) rating for Binary Insertion sort. It is log2 n, not n log n, like Quicksort and Merge Sort.

I can't study your code - you still don't use the [CODE ] tags [/COD E] around your code.

With random integers, and less than 20 numbers, Insertion sorts win the sorting race,
packed behind it VERY tightly, are all the other sorting algorithms, including Quicksort and Mergesort. To detect any differences, you need to sort 100's of these small randomized arrays of integers, in a timed run. In one run, your computer may not see any difference in time - reporting 0.0000 seconds for the sort.

50 to 100, several of them tie: Quicksort, Mergesort, Insertion sort (both of them), Shell sort, Comb sort 11, Heap sort, Bubble sort, Selection sort. The computer shows no time was used, by any of the sorting runs. Again, if you want to see any differences at all, you have to make several runs of these small arrays, into one timed event. A single sort of 50 to 100 integers will still show 0.0000 elapsed seconds. (depending on your timing hardware and software)

With 1,000 random int's or more, you can see:

*Quicksort, Merge sort, Heap sort, are tied with Comb sort 11 and Shell sort, for first place.

  • Binary Insertion starts to edge out regular Insertion sort, enough that the computer can detect the difference (sometimes) in timed runs. Both of these are just a small amount …
Adak 419 Nearly a Posting Virtuoso

Please double check that you can use conio.h, because it's an older program, (mine is 16 bit, for instance), and unless it's been re-compiled, won't run on Windows 7 (will run on WindowsXP I know).

Adak 419 Nearly a Posting Virtuoso

Multi merge sorting can be optimized to fit the architecture of a computer system, to produce an outstanding sorter.

An example is the champion sorting program "Psort", which you can read more about by Googling it.

In my testing, Binary insertion is better than the normal Insertion sort, and both will beat anything else, with small or almost sorted, data.

With random data, both Insertion sorts will beat anything else, but that applies only to random int arrays with fewer than about 100 numbers. After that, Quicksort, Merge sort, Comb sort 11, and Shell sort (with an optimal series), begin to sort just as fast as either type of Insertion sort.

Where their sort times are equal will vary from system to system, and with specifics of the randomized data. The best numerical sorters (Quicksort Merge sort, and Heap sort), don't begin to really pull away, until you have tens or hundreds of thousands of numbers to be sorted. Again, that point depends on your system, but it will be reached, if you repeat the sorting, sequentially, for large arrays. (That is, I use arrays of 20,000 or so, and set it up so I can test it by having it sort any number of 20k arrays of changing randomized numbers, with the time being measured for ALL the arrays to be sorted).

Having either type of Insertion sort handle the smaller sub arrays of Quicksort, gives Quicksort a nice speed up. That is my …

Adak 419 Nearly a Posting Virtuoso

I'd like you to check your book's index for rand(), or your man pages (if you're on Linux), or your help icon, if you're on Windows, search the forum for "rand()", or even Google "rand() in C".

When you have a specific problem with your code, then post your code, and be specific about what the problem is.

We try to solve problems with C programs, but tutoring is substantially different, and forums are not good places to tutor from. C (like all programming languages), requires way too much detail for posts that are expected to be virtually unviewed, within a month or less.

Adak 419 Nearly a Posting Virtuoso

He's taking care of the inner array (the row). Your code is giving his code a new outer array.

You take care of the top part of this, and his code takes care of the lower part:

//Your code does this part:
  double **dat2;
  /*  allocate outer array (all pointers)  */
  dat2 = malloc( nrows*sizeof(double*));
     
  if(dat2==NULL) {
    printf("\nError allocating memory\n");
    exit(1);
  }
   // The teacher's code does this part, (all sized for data type)
  /*  allocate each row  */
  for(i = 0; i < nrows; i++) {
    dat2[i] = malloc( ncols*sizeof(double));
  }

I believe that's correct. Ignore that the data type here is a double.

Adak 419 Nearly a Posting Virtuoso

Kim, the arrangement of the data, makes this quite awkward.

A normal arrangement might be:

data/time string
number1
number2
number3
...
etc.
Which is very easy to retrieve from a file, put into an array, etc.

It's VERY unusual to have a row of data that's over 450 char's in length!!

Anyway, this shows how you can get the data (there is one string and 18 numbers), from the file. I've run this through your 1 row of data a few times, but I have not really tested it, nor is it put into an array. It just prints it up. You should be able to take it from there.

#include <stdio.h>
#define SIZE 500

int main() {
  int i,j, k,count=0; 
  char line1[SIZE];
  double n=0.0L;
  FILE *fp;

  printf("\n\n\n");
  fp=fopen("0kim.txt","r");
  fgets(line1, sizeof(line1), fp);
  i=0;
  while((line1[i]) != 'M') { //print dateTime string
    putchar(line1[i]);
    ++i;
  }
  putchar(line1[i]);
  k=i;
  while(line1[i]) {  //remove all comma's
    if(line1[i]==',') {
      for(j=i;line1[j];j++) 
        line1[j]=line1[j+1];
    }
    ++i;
  }  
  i=k;
  while(line1[i]) {   //wax on get number, wax off ;)
    while(line1[++i]<'0' && line1[i]); 
    if(i==SIZE-1) break;
    sscanf(line1+i, "%lf", &n); 
    count++;
    printf("\n%3d) %9.2lf", count, n);
    while(line1[++i] != ' ' && line1[i]);
  }  
  fclose(fp);
  printf("\n\n\t\t\t     press enter when ready");

  (void) getchar(); 
  return 0;
}
Adak 419 Nearly a Posting Virtuoso

You DO have a char ** pointer that you are saving now, RIGHT? Each char ** pointer IS separate, and must be saved separately.

An array of char ** would be a good way to go, I believe. Separate that way, but also organized.

Adak 419 Nearly a Posting Virtuoso

I tested the program here, several more times, and it's much worse than I thought:

1) It crashes abruptly without an error message, if you request more than 2700 as the upper limit. This is a major bug for a prime number testing program.

2) I compared it's run time, using 2,500 as the upper limit, against a quick prime number tester I wrote. (also only in standard C, no assembly here, no bit tricks, etc.). With minor differences, the logic is the same. My program is iterative though, not recursive.

My program also calls another function to test each number, returns that result, and gets the next number to be tested.

My program ran 488% faster, testing 12,200 numbers, in the same amount of time (0.055 seconds), that the OP's program tested 2,500 numbers.

This is only an estimate of the true performance of both programs, because the OP's program wouldn't work with any higher numbers.

Each program also printed out what number it had found, as it found it - just a short few words, and the number, and a newline.

Please test this program, on your system and with your compiler, and report what you find - maybe that dreadful upper limit bug is not happening on other compilers.

The OP should know if it is a common bug, so he can look into fixing it.

Adak 419 Nearly a Posting Virtuoso

You should know you can't print two things, at exactly the same time.

How you change colors for your text, depends on your operating system. For windows, you should probably use the Windows API for this. If your compiler supports conio.h, you might be able to use that. If your system has ansi.sys compatibility (and the ansi.sys driver is loaded), then you might be able to use it's way to color the text color. For linux user's, NCURSES has it's way of coloring text.

The list goes on...;)

In other words, more info is needed about your OS.

Adak 419 Nearly a Posting Virtuoso

Well, yeah. malloc() will always give you a "fresh" address for your pointer.

As I understand it now, your program has to create the array pointer, and the teacher's function, will create the row pointers.

How many images are you supposed to try and hold in memory, at one time? If it's not too many for your system, then I'd make ONE pointer array, and let teacher's code add the row pointers, and then I'd get ANOTHER ONE pointer array, and let the teacher's code add the row pointers, for that image, then malloc() ANOTHER ONE pointer array, and let the teacher's code add the row pointers, etc.

So the images are all in separate pointer addresses, but that's just what you need, I believe.

If that sounds wacko, then I'd say, go talk with some smart classmates, buy them a brew or taco or something, and find out what's up. Or check with the teacher.

I've never had an assignment where my code had to shoe horn in with the instructor's code, so closely.

Adak 419 Nearly a Posting Virtuoso

Now I'm confused what your assignment is. I thought YOU were supposed to dynamically declare a 2D array - irrespective of anything your teacher did in his code.

I doubt very much if the teacher intends for you to alter his code. The way I use 2D arrays is to create them, load the data, make the computations needed, and then reload that SAME array, with some more data.

Is your array supposed to be a 2D array, but you only malloc 1D of it, and the teacher's code mallocs the second D of it?

Adak 419 Nearly a Posting Virtuoso

It is because the variable is passed by address, that the continued need to dereference the pointer, becomes a run-time anchor.

The great thing about your program, is that it's simple to test it for yourself. Google up and d/l a few other others, and time them with your own system. Give them a target that requires at least 1 minute or so of run-time on your program. Then test several other versions, as well. See how they all stack up in run-time.

I believe you'll be surprised at how much slower your program is.

Adak 419 Nearly a Posting Virtuoso

His code doesn't seem to be relevant to the problem at hand.

1 Comment is inside the code

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

void menu();
void loadImg(unsigned char** images, int *n);

int main() {
	int numImages = 0;
	int curImage = 0, loop = 1, bool = 0, imgIndex=0;
	unsigned char **imgSet;
	
	while(loop != -1) {
		char choice;
		menu();
		scanf("%s",&choice);
		switch(choice) {
			case 'L':
			case 'l':
				imgSet = (unsigned char**)malloc((numImages+1)*(sizeof(unsigned char*)));

/* 888888888888888888888888888888*/
/*you are mallocing 1 * sizeof(unsigned char*), since numImage is 0 */
/* that looks OK, if unusual. */
/* 888888888888888888888888888888*/

				loadImg(imgSet,&numImages);
				printf("File has %d rows and %d columns\n",imgSet[numImages][0]+1,imgSet[numImages][1]+1);
				break;
			case 'Q':
			case 'q':
				printf("Program terminated\n");
				loop = -1;
				break;
		}
	}
	
	return 0;
}

void menu() {
	printf("*****OPTION*****MENU*****\n");
	printf("L: Load image\n");
	printf("R: Remove image\n");
	printf("P: Print image\n");
	printf("A: Average image\n");
	printf("H: Horizontal derivative\n");
	printf("V: Vertical derivative\n");
	printf("T: compute hisTogram\n");
	printf("D: search Digram\n");
	printf("M: local Maxima\n");
	printf("Q: Quit program\n");
	printf("*************************\n");
	printf("Select an option: ");
}

void loadImg(unsigned char** images, int *n) {
	char fileName[80];
    printf("Enter filename: ");
    scanf("%s",fileName);
    readImage(&fileName,&images[*n]);
	printf("File %s has %d rows and %d columns\n",fileName,images[*n][0]+1,images[*n][1]+1);
    (*n)++;
}

Big problem is, I don't see where you malloc the row (the second dimension) pointers.

Look at my allocate2D() function again, there needs to be two malloc's - one for the valid array pointer, and one (loop) for mallocing each of the row pointers.

At the end of your program, you should also free them, and free them in the order …

Adak 419 Nearly a Posting Virtuoso

Well, there is an easier and more efficient way to generate non-repeating random numbers. The algorithm is:

generate all the (non random) sequential numbers you need, and put them into an array (any data structure would perhaps do, but an array is easy).

Then shuffle the numbers in the array, randomly. Aha!

Then take the randomized numbers, in order, by their index: num[index].

Since all the numbers were unique to start with, and you've shuffled them around the array, in a random fashion, you're guaranteed a unique (pseudo) random number.

Most random numbers generated by non-professionals, are skewed in some way (which may not matter a bit to you and your program - you may not even notice it). There is a real art to generating good (pseudo) random numbers, however - not for beginners.

Adak 419 Nearly a Posting Virtuoso

Entirely welcome.

I can't tell by little snippets of code that you've posted, but no, you're not doing what I did in the second version of the program, in this thread.

You MIGHT be doing what I did in the first version, and not returning the address that is malloc'd, but i can't tell stink from these little bits of code you've posted.

Post the code up, if you want help. I can see very little, looking through a straw. ;)

Adak 419 Nearly a Posting Virtuoso

I prefer where the numbers being tested are incremented by two, since no even number can be prime. Why test them at all? Only testing the odd numbers, cuts the work in half, straightaway.

Also, I prefer a more concise coding. Not

rem = *num % *div; /* Calculate the remainder */

if(rem == 0)            /* If the remainder is 0, then num is not prime */
   *isPrime = FALSE;
  
//but:
if(*num % *div)
  *isPrime=FALSE;
else
  *isPrime=TRUE;

The comments are too verbose - the obvious code we need no comments on, imo. It's distracting, actually.

Nothing wrong with doing the testing in another function, but it does slow things down when you have to work through a pointer, time after time. With a very large number to be tested (or several very large numbers), the run-time jumps considerably.

I realize you're not coding for some Cryptographic endeavor, but after accuracy, I start putting a lot of emphasis on clarity and faster run-time/efficiency. Your code is easy to read, which is good.

I didn't catch the reason for TEST_EVEN being a test for even integers, when it's a floating point number.

Adak 419 Nearly a Posting Virtuoso

Many apologies, but that last program was NOT the right version:

Try this one: (and delete that other one):

/* dynamically creates a 2D array of pointers, in C */

#include <stdio.h>
#include <stdlib.h>

double** allocate2D(int nrows, int ncols);

int main() {
  int i,j, rows, cols; 
  double **dat;

  printf("\n\n\n How many rows do you want?\n ");
  scanf("%d", &rows);
  (void) getchar();
  printf(" How many columns do you want?\n ");
  scanf("%d", &cols);
  (void) getchar();

  dat = allocate2D(rows, cols);
  for(i=0;i<rows;i++) {
    for(j=0;j<cols;j++) {
      dat[i][j] = i+j;
    }
  }

  for(i=0;i<rows;i++) {
      for(j=0;j<cols;j++) 
        printf("\n%.3lf", dat[i][j]);
  }
   
  for(i=0;i<rows;i++)
    free(dat[i]);

  free(dat);
  printf("\n\t\t\t    press enter when ready");
  (void) getchar();
  return 0;
}
double** allocate2D(int nrows, int ncols) {
     int i;
     double **dat2;
     /*  allocate array of pointers  */
     dat2 = malloc( nrows*sizeof(double*));
     
     /*  allocate each row  */
     
     for(i = 0; i < nrows; i++) {
          dat2[i] = malloc( ncols*sizeof(double));
     }
    if(dat2==NULL || dat2[i-1]==NULL) {
       printf("\nError allocating memory\n");
       exit(1);
    }
  return dat2;
}

The problem with my earlier post, is that it didn't return the address that malloc was assigning, to dat. :(

Since I can't edit that bad post, that will just be a lesson to anyone in a hurry, who doesn't read through the posts. ;)

Adak 419 Nearly a Posting Virtuoso

Welcome to the forum, Subclass! ;)

/* dynamically creats a 2D array of pointers, in C */

#include <stdio.h>
#include <stdlib.h>

void allocate2D(double **dat, int nrows, int ncols);

int main() {
  int i,j, rows, cols; 
  double **dat;
  
  printf("\n\n\nEnter the number of rows and columns you want: \n");
  scanf("%d %d", &rows, &cols);
  getchar();  //remove the newline from the kboard buffer
  
  
  allocate2D(dat, rows, cols);
  
  for(i=0;i<rows;i++) {
    for(j=0;j<cols;j++) {
      dat[i][j]= i+j;
    }
  }

  for(i=0;i<rows;i++) {
    printf("\n%.3lf %.3lf %.3lf", dat[i][0],dat[i][1],dat[i][2]);
  }

  //free the memory correctly
  for(i=0;i<rows;i++)
    free(dat[i]);
  free(dat);

  return 0;
}
void allocate2D(double **dat, int nrows, int ncols) {
     int i;
     /*  allocate array of pointers  */
     dat = malloc( nrows*sizeof( double* ) );
     
     /*  allocate each row  */
     
     for(i = 0; i < nrows; i++) {
          dat[i] = malloc( ncols*sizeof( double ) );
     }
    if(dat==NULL || dat[i-1]==NULL) {
       printf("\nError allocating memory\n");
       exit(1);
    }
   
}
Adak 419 Nearly a Posting Virtuoso

The normal template for a simple C program is:

#include files listed    //no semi-colons at the end of these lines of code

#defines SIZE 20  //no semi-colons at the end of these lines SIZE in the code (everywhere), will be replaced by the number 20. 

function prototypes go here. These can be exactly the same
as the first line of the function (copy and paste), except,
they will have an added semi-colon at the end of them.

void function1(int number, char choice, double salary);
(could be shortened to just (int, char, double) parameters)

other global variables if needed (use very sparingly)

int main(void) {
  //declare your local variables, for main() here
  int number;
  char choice;
  double salary;

  //begin your program's logic code here
  //and/or 
  //call any other functions you might have

  function1(number, choice, salary); //call to function1 

  printf("\n\n\t\t\t    press enter when ready"); //if needed
  getchar(); //if needed to hold the console window open
  return 0;  //normal run signal to the OS
}
void function1(int number, char choice, double salary) 
{  //list of the local variables for function1 go here
   
   //logic goes here

   //this is a void function, so nothing to return to main
   //if a return was needed, it would go here (last line of code)
}

Note: in function1(), I have COPIES of number, choice, and salary,
NOT the original variables in main. If I want any changes to be
permanent, I need to send the address of these variables (using &,
ie:
function1(&number, …

Adak 419 Nearly a Posting Virtuoso

You probably don't want to hear this, but I feel obligated to say you should move up to a more robust language. QBasic (unless it's the rarer QBasic Pro version), can't even create an executable file.

Lots of ways to do this. Maybe something as simple as this:

Your data file will have even numbered rows of text, for the questions, and use the odd numbered rows of text, for the answer.

You could display both of them easily, by reading in an even numbered row first (never an odd numbered row), and then having row+1, be the answer to that question.

You could certainly get more organized with this: using records and fields, but that sounds like it's more than you need.

Adak 419 Nearly a Posting Virtuoso

You have no deleteline function(), you just included some code for it, inside main().

You should add a function prototype above int main(), like:

void deleteline(char *pnum);

//then your actual function (located OUTSIDE main(), would begin with:
void deleteline(char *pnum) {
  //put your deleteline function, in here. 

  //gotta love that copy and paste! 
  }

please set your editor up, like WaltP has suggested. Your code is almost unreadable, in it's current form.

The above may not solve your delete problem, but you need to do this FIRST, and THEN you can tell me what's wrong with it, altogether. Hopefully, by then I can see the whole program, on one page width.

There is some nice code in deleteline. It's just in the wrong place, and may need a bit of a touch up.

Back in a few hours to see how you're doing.

Adak 419 Nearly a Posting Virtuoso

You only get code tags by clicking on the icon, in the editing window, and pasting your code, between the tags it provides.

I'm putting together a program from your code, and have found a few odd errors, but I need to have you post the delete() function code. The code here, calls that function, to actually delete the number. This code just gets the number, and adds it to the end of the file.

No deletions going on here.

I'm too tired to continue this morning, but post up the delete function, and I'll get to it tomorrow. Perhaps others will get to it even sooner.[CODE ] icon, in the editing window, and pasting your code, between the tags it provides.

I'm putting together a program from your code, and have found a few odd errors, but I need to have you post the delete() function code. The code here, calls that function, to actually delete the number. This code just gets the number, and adds it to the end of the file.

No deletions going on here.

I'm too tired to continue this morning, but post up the delete function, and I'll get to it tomorrow. Perhaps others will get to it even sooner.

Adak 419 Nearly a Posting Virtuoso

Can you quickly edit the program, highlight the code, and click on the CODE icon in the editing window?

Almost impossible to study code, that is smashed over all to the left hand side like html text.

Adak 419 Nearly a Posting Virtuoso

The only function I would add, is a calculate() function, that would start with the while loop, and extend down to just before the fclose(InFile), line of code. Every variable you use in the while loop, needs to be brought down into the new function, as a parameter. It doesn't need to return any value, so a void function would be fine.

The printing is all tightly integrated into the calculations, so I wouldn't try to make a separate function for that.

In C, it's always int main(void) or int main(argc, *argv[]) , never just main(), and always with a return 0 at the very end of main().