samedi 27 juin 2015

What's the difference between GtkApplication and gtk_init?

I am now learning to use GTK+3.0 with C in Linux. After reading some tutorials and sample code, I have some questions regarding how to initialize an application.

Here are two versions of code I have seen.

#include <gtk/gtk.h>

static void
activate (GtkApplication* app,
          gpointer        user_data)
{
  GtkWidget *window;

  window = gtk_application_window_new (app);
  gtk_window_set_title (GTK_WINDOW (window), "Window");
  gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
  gtk_widget_show_all (window);
}

int
main (int    argc,
      char **argv)
{
  GtkApplication *app;
  int status;

  app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
  g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
  status = g_application_run (G_APPLICATION (app), argc, argv);
  g_object_unref (app);

  return status;
}

This code used gtk_application_new() to init a GtkApplication and g_application_run() to start it.

This is the second one.

#include <gtk/gtk.h>

int main(int argc,char *argv[])
{
  GtkWidget *window;
  gtk_init(&argc,&argv);

  window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(window),"helloworld");
  gtk_widget_show(window);
  gtk_main();

  return 0;
}

This code used gtk_init() to init the application and gtk_main() to run it.

However, I can't figure out the difference between them as the running result seems the same.

Replacing multiple new lines in a file with just one

This function is supposed to search through a text file for the new line character. When it finds the newline character, it increments the newLine counter, and when there are more than 2 consecutive blank new lines, its suppose to squeeze all the blank lines into just one blank line.

In my code if there are 2 new lines it's suppose to get rid of them and squeeze them into one, for testing purposes I also have it printing "new line" when it reaches the newLine < 2 condition. Right now it prints new line for every new line, whether its blank or not, and its not getting rid of the extra new lines. What am I doing wrong?

EDIT: HERE IS MY FULL CODE http://ift.tt/1GSqY1v

So basically the program is suppose to concatenate two files together and than perform various operations on them, like what I'm trying to do which is get rid of multiple consecutive blank new lines. So in order to execute it in cygwin I do ./a -s file1 file2 Its suppose to concatenate file1 and file2 together into a file called contents.txt and than get rid of the consecutive new lines and display them on my cygwin terminal (stdout). (the -s calls the function to get rid of the consecutive lines). The third and fourth arguments passed in (file1 and file2) are the two files its suppose to concatenate together into one file called contents.txt The squeeze_lines function than reads the contents.txt file and is suppose to squeeze new lines. You can see below for an example for the contents I put in file1.txt. file2.txt just has a bunch of words followed by empty new lines.

int newLine = 1;
int c; 

if ((fileContents = fopen("fileContents.txt", "r")) == 0) 
{
    perror("fopen");
    return 1; 
}

while ((c = fgetc(fileContents)) != EOF)
{   
    if (c == '\n')
    {
        newLine++;
        if (newLine < 2) 
        {
            printf("new line");
            putchar(c); 
        }
    }
    else 
    {
        putchar(c); 
        newLine = 0;
    }
}

The file the program reads in a .txt file with these contents. Its suppose to read the file, get rid of the leading, and consecutive new lines, and output the new formatted contents to stdout on my cywgin terminal.

/* hello world program */


#include <stdio.h>

    tab
            2tabs

Why getting out of memory exception when trying to play images in pictureBox?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace Player_Manager
{
    public partial class ScreenShotsPlayer : Form
    {
        FileInfo[] images;
        DirectoryInfo di1;
        int current = 0;

        public ScreenShotsPlayer()
        {
            InitializeComponent();

            di1 = new DirectoryInfo(@"e:\screenshots");
            images = di1.GetFiles("*.bmp");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            timer1.Start();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            current = (current >= images.Length - 1) ? 0 : ++current;
            pictureBox1.Image = new Bitmap(images[current].FullName);
            pictureBox1.Refresh();
        }
    }
}

There are 1200 images on the hard disk and the timer is set to 100ms. After about 258-270 images played it's throwing the out of memory exception on the line:

pictureBox1.Refresh();

System.OutOfMemoryException was unhandled
  HResult=-2147024882
  Message=Out of memory.
  Source=System.Drawing
  StackTrace:
       at System.Drawing.Graphics.CheckErrorStatus(Int32 status)
       at System.Drawing.Graphics.DrawImage(Image image, Int32 x, Int32 y, Int32 width, Int32 height)
       at System.Drawing.Graphics.DrawImage(Image image, Rectangle rect)
       at System.Windows.Forms.PictureBox.OnPaint(PaintEventArgs pe)
       at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
       at System.Windows.Forms.Control.WmPaint(Message& m)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
  InnerException: 

If i will remove the line pictureBox1.Refresh(); Then it will throw the exception on:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Player_Manager
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

On the line Application.Run(new Form1());

Same exception.

Overwritting null character in C array

Consider the case:

char s1[] = "abc";
s1[3] = 'x';
printf("%s", s1);

As I know, printf prints characters until it finds the null character and then stops.

When I overwrite the null character by 'x', why does printf print the s1 array correctly? How does it find the null character?

Create pyside widget in C/C++

I have a very complex custom widget derived from QWidget in PySide.

At first its paintEvent was taking more than 1sec to complete. Then I've implemented a lot of caching with QPixmap to each layer of the "image" that I'm drawing. Now my paintEvent finishes in about 90ms, that is really fine, but not enough.

I'm wondering if I can implement this custom widget in plain C or C++ and them use it as an abstract widget in PySide (like PySide does with all other available widget).

I found here that in PyQt I could use sip for this. But I can't find a match for this in PySide.

Does any one knows who to do that?

Array of chars to linked list - Using the address in array

i am trying to pass words from a string to a linked list, the thing is, i can't reallocate memory to my string inside my struct, i should be using the address of each word inside the array.

my struct:

typedef struct slist{
    char *string;
    struct slist * prox;
} *SList;

my function:

int words (char t[], SList *l){
    int i, p;
    p=0;
    *l = (SList) calloc(1, sizeof(struct slist));

    SList aux = NULL;


    SList li = *l;
    for(i=0; t[i]!='\0' ;){
        aux = (SList) calloc(1, sizeof(struct slist));

        li->string = &t[i];
        li->prox = aux;
        li = aux;

        while(t[i]!=' ') i++;

        //t[i++] = '\0'; -> this doesn't work, bus error 10;

        while(t[i]==' ') i++;

        p++; //This counts words
    }

    return p;

}

This works, kind of, my doubt is, i can't change the initial array to include a NULL char at the end of each word (Strings declared in C are read-only right?)

So, i tried to add the t[i]='\0' in vain.

At this moment, running the code with this string

char *str = "this is one sentence";

will get me the following strings in my linked list:

this is one sentence
is one sentence
one sentence
sentence

the expected result is not this one, it should add the NULL char after the first word inside my list->string

PS: The linked list is not well defined, it adds a NULL at the end unnecessarily but i can deal with that later on.

Thank you for your help!

the C program does not execute the function outside the main

If I execute the exec() function in another C program as a main function it works perfectly, while if I put it as a function called in the main menu it gives me some warning and the function does not run.

My code:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> /* for fork */
#include <sys/types.h> /* for pid_t */
#include <sys/wait.h> /* for wait */

int exec (void) {

        char array[100];
        char character;
        int i = 0;
        char* point;
        int j = 0;

        printf ("Digita una stringa");
        printf ("\n");
        do {
            character = getchar();
            array[i] = character;
            i++;
        }
        while (character != '\n');
        array[i-1] = '\0';
        i = 0;

        char* string[100];

        char *word = strtok(array, " .");
        j = 0;
        while (word != NULL) {
            printf("%s\n", word);
            string[j++] = word; // Increment j
            word = strtok(NULL, " .");
        }
        string[j] = NULL; // Make sure the array is NULL term

        printf ("\n");  

    pid_t  pid;
    pid = fork();
    int status;

    if (pid == -1) {
        perror("");
    }else if (pid == 0) {
        execvp(string[0], string);     /* execute the command  */
                fprintf(stderr, "Failed to exec");  
                exit(1);
            }
    else {

        //.. wait until the child ends
        waitpid(-1, &status, 0);
      }

return;
}

int read_input (void) {
    int choice;
    printf("Seleziona una voce dal menu");
    do {    
        printf("\n");
        scanf ("%i", &choice);
        if (choice > 8 || choice < 1)
            printf ("Attenzione, inserisci un valore contemplato dal menu");
    }
    while ( choice > 8 || choice < 1);

return choice;
}

void main (int argc, char *argv[]) {

    printf ("------------------------\n");
    printf ("          MENU         \n");
    printf ("------------------------\n");
    printf ("  \n");
    printf ("1) Esecuzione in foreground di un processo\n");
    printf ("2) Ctrl -C\n");
    printf ("3) Exit\n");
    printf ("4) Background\n");
    printf ("5) Pipe\n");
    printf ("6) Jobs\n");
    printf ("7) fg\n");
    printf ("8) kill\n");
    int menu = read_input();
    switch (menu) {

        case '1' :  
                exec ();
                break; 
        case '2' :
                //ctrl();
                break;
        case '3' :
                //exit_();
                break; 
        case '4' : 
                //background();
                break;
        case '5' :
                //pipe();
                break;
        case '6' : 
                //jobs();
                break;
        case '7' : 
                //fg();
                break;
        case '8' : 
                //kill();
                break;
    }
}

this is the warning:

elaborato.c:31:16: warning: initialization makes pointer from integer without a cast [enabled by default] char *word = strtok(array, " .");