First of all Sorry for my bad English. I am not native English.
I am going to write a program that list all available logical disk drives. Then ask the user to select a drive. then takes a file extension and searches that file type in given drive (including directories and sub-directories). Program should be able to run on windows xp and onward. It should be single stand alone application. I am not expert in C. I have some hands on C#. i have following questions in this regard.
1. Is there any IDE/Tool in which i can write C# like code that directly compiles to single stand alone application for windows?
2. Can you recommend some libs that i can use state forward for this purpose like using in C#? (I have seen dirent and studying it.)
I coppied some code that i am testing as a startup.
#include <windows.h>
#include <direct.h>
#include <stdio.h>
#include <tchar.h>
#include<conio.h>
#include<dirent.h>
//------------------- Get list of all fixed drives in char array. only drive letter is get. not path.
// add ":\" to build path.
char AllDrives[26];
DWORD GetAllDrives()
{
int AvlDrives=0;
DWORD WorkState=-1;
//TCHAR DrivePath[] = _T("A:\\"); //Orignal Type
//start getting for drive a:\ to onward.
char DrivePath[] = {"A:\\"};
//http://www.tenouk.com/cpluscodesnippet/getdrivetype.html
ULONG uDriveMask = _getdrives();
if (uDriveMask == 0)
{
WorkState=GetLastError();
printf("\r\nFailed to Get drives. Error Details : %lu", WorkState);
return WorkState;
}
else
{
WorkState=0xFF;
printf("The following logical drives are being used:\n");
while (uDriveMask) {
if (uDriveMask & 1)
{
UINT drvType=0;
drvType = GetDriveType(DrivePath);
if(drvType==3)
{
AllDrives[AvlDrives]= DrivePath[0];
AvlDrives++;
printf("\r\n%s",DrivePath);
}
}
++DrivePath[0]; //Scan to all scanable number of drives.
uDriveMask >>= 1;
}
}
return WorkState;
}
int main(int argc, char* argv[]) {
char DrivePath[]={"C:\\"};
char CurrentDrive[]={"C:\\"};
DWORD Drives=-1;
int d=0;
for( d=0; d<26; d++)
AllDrives[d]=' ';
Drives=GetAllDrives();
if(Drives >0)
{
int Length= sizeof(AllDrives);
for(int x=0; x<26; x++)
{
if(AllDrives[x]!=' ')
{
printf("\r\nFixed Drive : %c",AllDrives[x]);
}
}
}
getch();
}
You can use visual studio compiler to compile C and C++ in Windows, and it is available with its own IDE. When you install visual studio, it will install required libraries also to compile the C/C++ program. There are other IDEs and compilers available compatible with Windows like DevC++,CodeBlocks.
Related
I'm writing a package manager for the Termux terminal emulator on android using the APK format. The program is written in C and uses various arguments like 'sync', and 'remove'. However, the function I have written doesn't recognize the argument I have written for the name of the package to 'sync'. 'sync' is meant to download an apk from the fdroid repositories and open it using xdg-open (not yet implemented) using the name of the apk given in the arguments.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void syncapk(char * apkname);
int main(int argc, char **argv)
{
if(argc==1) {
printf("Displaying help screen.\n");
} else if(argc>=2) {
if(strncmp(argv[1], "sync\n", 4) == 0) {
syncapk(argv[2]);
} else if(strncmp(argv[1], "upgrade", 7) == 0) {
printf("Upgrading all packages!\n");
} else if(strncmp(argv[1], "remove", 6) == 0) {
printf("Removing package!\n");
}
}
return 0;
}
void syncapk(char * apkname) {
printf("Syncing package: %s!\n", apkname);
char * synccmd = "fdroidcl download %s", apkname;
system(synccmd);
}
GCC (my compiler) says that the argument (the name of the apk I wish to download from the repositories) is 'redeclared as a different symbol'. I am fairly new to writing programs in C so feel free to critique other things, not just the problem itself and whether I could take a different approach completely.
This doesn't do what you think it does:
char * synccmd = "fdroidcl download %s", apkname;
This is defining a variable of type char * named synccmd and a variable of type char named apkname. The latter conflicts with the parameter of the same name, hence the error.
If you want to build a formatted string, you need to use sprintf to do that:
char synccmd[100];
sprintf(synccmd, "fdroidcl download %s", apkname);
I want to use a dll-file in my C-Code, but are very confused about the syntax.
My Story: I made a simple function in Matlab ( f(x1,x2)=x1*x2 ), with the "Matlab Coder" I translated it to C-Code and generated an exe, I could run it from the terminal with arguments.Now I generated a dll instead of an exe and want to use the dll.
Since now I could not make Code explanations, I googled, make work for me. I look up Syntax in http://en.cppreference.com/w/ but for my surprise there wasn't even an entry for e.g. GetProcAddress or LoadLirbary.
Here is the C-Code in which I would like to use the dll:
#include <stdio.h>
#include <stdlib.h>
/*
* In my dream I would load the dll function here
* with something like Load(mytimes4.dll)
*/
int main(int argc, char *argv[]) {
double x1,x2,myresult;
//Load Arguments from Terminal
sscanf(argv[1], "%lf", &x1);
sscanf(argv[2], "%lf", &x2);
// Use and print the function from mytimes4.dll
myresult = mytimes4(x1,x2);
printf("%3.2f\n",myresult);
return 0;
}
After generating the dll, Matlab gave me the following folder:
"dll-folder" produced by Matlab
Can someone give me a most simple but complete Code that would work with my example? What files are needed (maybe .def or .exp)? Also for Explanations of the lines involved using the dll I would be gratefull. Or if not, you maybe have some background knowledge that makes the complex syntax reasonable.Thanks in advance!
System information: Windows 7 Pro 64, Matlab 64 2016b, gcc cygwin 64, eclipse ide.
With the link of thurizas I could solve my problem.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms686944(v=vs.85).aspx
I copied the code from the side. Below you can see the code with additional comments of mine and with ,in my opinion, more clearly naming. Thus it is probably easier to use for beginners as I am.
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
/*Declaration of the function,contained in dll, as pointer with the arbitrary pointer name
"*MYFUNCTIONPOINTER" (not sure if it has to be in big letters).
In my case the function means simply f(x1,x2) = x1*x2 and is thus as double declared*/
typedef double (*MYFUNCTIONPOINTER)(double, double);
int main() {
HINSTANCE hinstLib;
//"myfunction" is the arbitrary name the function will be called later
MYFUNCTIONPOINTER myfunction;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
//Tell the dll file
hinstLib = LoadLibrary(TEXT("mypersonal.dll"));
if (hinstLib != NULL)
{
/* At this line "myfunction" gets its definition from "MYFUNCTIONPOINTER"
and can be used as any other function.The relevant function in the dll has
to be told here.*/
myfunction = (MYFUNCTIONPOINTER) GetProcAddress(hinstLib, "mydllfunction");
// If the function address is valid, call the function.
if (NULL != myfunction)
{
fRunTimeLinkSuccess = TRUE;
// The function can be used.
double myoutput;
myoutput = myfunction(5,7);
printf("%f\n",myoutput);
getchar();
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
// If unable to call the DLL function, use an alternative.
if (! fRunTimeLinkSuccess)
printf("Message printed from executable\n");
return 0;
}
I've got some code which generates an array of strings of different file names and then
passes them into a function to write some data to them. It adds a incrementing number to the starting filename which is supplied from an input argument.
The problem is that it works fine running from source in Visual Studio 2012 but when I compile it and run it as an .exe the program crashes.
The .exe doesn't appear to be passing the array of strings properly which is causing an error when it attempts to use the string
for opening a file etc.
Here is the isolated bit of code
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <string.h>
#include <stdint.h>
#include <Windows.h>
void processing_function(int num_output, char **outnames)
{
/* in Visual Studio this works fine and prints all
the names correctly. Running from .exe will crash */
for(int idx = 0; idx <num_output;idx++)
{
printf("outnames[%d] is %s\n",idx,outnames[idx]);
}
}
int main(int argc, char *argv[])
{
/*nframes comes from another function, outname comes from input arguement */
int num_output = ceil(((double)*nframes / 1100));
int outname_len = strlen(outname)+1;
char *out_right;
out_right = (char*) malloc(sizeof(char)*outname_len);
/*Split string to append numbers before file extension */
strcpy(out_right,outname);
strrev(out_right);
strtok(out_right,".");
strcat(out_right,".");
strrev(out_right);
int out_right_len = strlen(out_right);
strtok(outname,".");
strcat(outname,"-");
int out_origlen = strlen(outname);
int num_len = 1;
char **outnames;
char *num;
char *outname_tmp;
outnames = (char**) malloc(sizeof(char)*(num_output));
int out_len;
double dbl_idx;
int *numfs = (int*)malloc(sizeof(int)*num_output);
for(int idx = 1;idx <num_output+1;idx++)
{
/*convert output number to string and stitch complete name back together and place into array */
num_len = ceil(log10((double)idx+0.1));
num = (char*) malloc(sizeof(char)*(num_len+1));
outname_tmp = (char*) malloc(sizeof(char)*(out_origlen+num_len+out_right_len+1));
strcpy(outname_tmp,outname);
sprintf(num,"%d",idx);
strcat(outname_tmp,num);
free(num);
strcat(outname_tmp,out_right);
outnames[idx-1] = (char*) malloc(sizeof(char)*(out_origlen+num_len+out_right_len+1));
strcpy(outnames[idx-1],outname_tmp);
free(outname_tmp);
printf("%s\n",outnames[idx-1]);
}
free(out_right);
processing_function(num_ouput, outnames)
return(0);
}
EDIT: Changed num_input to num_output as they do have the same value.
Running from .exe will sometimes start printing some of the names and then crash, opening the
debugger gives an error within output.c, with an access reading violation. I tried putting this code at
the top of the processing_function but that gave further problems downstream (heap corruption), which makes me think that the
code is messing up the memory but I can't see whats wrong with it, nor why it would work in VS but not as a .exe.
I could try and dodge the issue by generating the next output name on the fly every time it requires one but I'd really rather know why this isn't working.
Any help would be greatly appreciated.
I am going to take a shot and say, you passed num_input to processing_function() with outnames, outnames was allocated with num_output for size, but num_input and num_output have different values at runtime. So that lets processing_function() access out of bounds.
I used to develop Java project by Eclipse.
A Java project can contain many code files with the main function (the entry point), so we can run each code file which has a main function.
But now I want to develop C project by Eclipse CDT.
In a C project we can have only one main function. Can I have many code files with a main function and run each file just like I would in Java?
P.S.: I don't like to write Make Target for each file by main self
Javas option to have a main in every object is highly irritating and does not make sense to me.
I assume you want to train a bit in c and want to find a way to have all training lessons in one file. Here is an option that would do that for you in a crude way. This would not be reasonable to do as an application but you can use this to execute different options.
To use this you would call your program like 'progname 1'.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int ProgrammingLesson001(void);
int main(int argc, char * argv[])
{
int i;
int option;
int e = 0;
printf("%i\n", argc);
for(i = 0; i < argc; ++i)
{
printf("%s\n", argv[i]);
}
if(2 == argc)
{
option = atoi(argv[1]);
printf("Your Option was '%s' interpreted as %i\n", argv[1], option);
}
else
{
option = 0;
e |= 1;
}
switch(option)
{
case 0:
printf("zero is an error\n");
e |= 1;
break;
case 1:
e |= ProgrammingLesson001();
break;
default:
break;
}
if(0 != e)
{
printf("an error has occureed\n");
}
return e;
}
int ProgrammingLesson001(void)
{
printf("This could behave like a main for training purposes\n");
}
If you spent some time programming in c take a second look at makefiles.
You can create a makefile that will fit all your programs.
This reduces the actual work you need to put into this so much that maintaining the switch construct is harder than creating a new project.
Thank Clifford to fixed my quest and guys who replied
I have solved this problem by myself
Here is my solution:
#!/bin/bash
SourceFile=$1
Path="$(dirname "$SourceFile")"
ParentPath="$(dirname "$Path")"
OutputPath="$ParentPath/bin"
OutputFile="$OutputPath/a.out"
mkdir -p $OutputPath
rm -f $OutputFile
gcc -w $SourceFile -lm -o $OutputFile
$OutputFile
This bash's name is gcc.sh
In eclipse run -> external tools -> external tools configurations -> new a configuration
Location: /home/xxxxx/gcc.sh
Working Directory: (just let it be empty)
arguments: ${resource_loc}
Then you can run C file by your customize command
A while ago I wrote a script in C that used the Windows API functions EnumWindows, SetWindowPos and SetForegroundWindow to automatically arrange windows (by title) in a particular layout that I commonly wanted.
Are there Linux equivalents for these functions? I will be using Kubuntu, so KDE-specific and/or Ubuntu-specific solutions are fine.
The best way to do this is either in the window manager itself (if yours supports extensions) or with the protocols and hints designed to support "pagers" (pager = any non-window-manager process that does window organization or navigation things).
The EWMH spec includes a _NET_MOVERESIZE_WINDOW designed for use by pagers. http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html#id2731465
Raw Xlib or Xcb is pretty rough but there's a library called libwnck specifically designed to do the kind of thing you're talking about. (I wrote the original library long ago but it's been maintained by others forever.) Even if you don't use it, read the code to see how to do stuff. KDE may have an equivalent with KDE-style APIs I'm not sure.
There should be no need to use anything KDE or GNOME or distribution specific since the needed stuff is all spelled out in EWMH. That said, for certain window managers doing this as an extension may be easier than writing a separate app.
Using old school X calls directly can certainly be made to work but there are lots of details to handle there that require significant expertise if you want to iron out all the bugs and corner cases, in my opinion, so using a WM extension API or pager library would be my advice.
#andrewdotn has a fine answer there but you can do this old school as well fairly simply by walking the tree starting at the root window of the display using XQueryTree and fetching the window name with XFetchName then moving it with XMoveWindow. Here is an example that will list all the windows and if any are called 'xeyes' they get moved to the top left. Like most X programs, there is more to it and this should probably be calling XGetWindowProperty to fetch the _NET_WM_NAME extended window manager property but the example works ok as a starter. Compile with gcc -Wall -g -o demo demo.c -lX11
#include <X11/Xlib.h>
#include <stdio.h>
#include <string.h>
static int
EnumWindows(Display *display, Window window, int depth)
{
Window parent, *children;
unsigned int count = 0;
int r = 1, n = 0;
char *name = NULL;
XFetchName(display, window, &name);
for (n = 0; n < depth; ++n) putchar(' ');
printf("%08x %s\n", (int)window, name?name:"(null)");
if (name && strcmp("xeyes", name) == 0) {
XMoveWindow(display, window, 5, 5);
}
if (name) XFree(name);
if (XQueryTree(display, window, &window, &parent, &children, &count) == 0) {
fprintf(stderr, "error: XQueryTree error\n");
return 0;
}
for (n = 0; r && n < count; ++n) {
r = EnumWindows(display, children[n], depth+1);
}
XFree(children);
return r;
}
int
main(int argc, char *const argv[])
{
Display *display = NULL;
if ((display = XOpenDisplay(NULL)) == NULL) {
fprintf(stderr, "error: cannot connect to X server\n");
return 1;
}
EnumWindows(display, DefaultRootWindow(display), 0);
XCloseDisplay(display);
return 0;
}
Yes, you can do this using the X Windows protocol. It’s a very low-level protocol so it will take some work. You can use xcb_query_tree to find the window to operate on, and then move it with xcb_configure_window. This page gives some details on how to do it. There’s a basic tutorial on using the library those functions come from, but you’ll probably want to Google for a better one.
It may seem daunting, but it’s not too bad. Here’s a 50-line C program that will move all your xterms 10px to the right:
#include <stdio.h>
#include <string.h>
#include <xcb/xcb.h>
void handle(xcb_connection_t* connection, xcb_window_t window) {
xcb_query_tree_reply_t *tree = xcb_query_tree_reply(connection,
xcb_query_tree(connection, window), NULL);
xcb_window_t *children = xcb_query_tree_children(tree);
for (int i = 0; i < xcb_query_tree_children_length(tree); i++) {
xcb_get_property_reply_t *class_reply = xcb_get_property_reply(
connection,
xcb_get_property(connection, 0, children[i], XCB_ATOM_WM_CLASS,
XCB_ATOM_STRING, 0, 512), NULL);
char* class = (char*)xcb_get_property_value(class_reply);
class[xcb_get_property_value_length(class_reply)] = '\0';
if (!strcmp(class, "xterm")) {
/* Get geometry relative to parent window */
xcb_get_geometry_reply_t* geom = xcb_get_geometry_reply(
connection,
xcb_get_geometry(connection, window),
NULL);
/* Move 10 pixels right */
uint32_t values[] = {geom->x + 10};
xcb_configure_window(connection, children[i],
XCB_CONFIG_WINDOW_X, values);
}
/* Recurse down window tree */
handle(connection, children[i]);
}
}
int main() {
xcb_connection_t *connection;
const xcb_setup_t *setup;
connection = xcb_connect(NULL, NULL);
setup = xcb_get_setup(connection);
xcb_screen_iterator_t screen = xcb_setup_roots_iterator(setup);
handle(connection, screen.data->root);
return 0;
}
There’s no error-checking or memory management, and what it can do is pretty limited. But it should be straightforward to update into a program that does what you want, or to turn it into a general-purpose helper program by adding command-line options to specify which windows to operate on and which operations to perform on them.
As it seems you are not looking specifically for a solution in code, but rather in a desktop environment, you need to take a look at one of the window managers that handle the window placement in such a desktop environment.
KDE's KWin's Window Attributes
Compiz (GNOME) has "Window Rules" and "Place Windows" in the CompizConfig Settings Manager application. See e.g. here
Openbox seems a lot harder to get right, although they link to a GUI tool at the bottom of this page.
The problem with using X directly is that X in itself knows nothing about your desktop environment (panels, shortcuts, etc.) and you'll have to compensate manually.
After googling for this, I'm surprised KDE is the only one that has a simple way to do this.